Skip to content

Feature Proposal: AI-Powered Gemini Semantic Email Classifier - #492

Open
don-petry wants to merge 55 commits into
mainfrom
feature/ai-gemini-classifier-proposal
Open

Feature Proposal: AI-Powered Gemini Semantic Email Classifier#492
don-petry wants to merge 55 commits into
mainfrom
feature/ai-gemini-classifier-proposal

Conversation

@don-petry

@don-petry don-petry commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

User description

Ref #491. Adds Feature Proposal 001 for Native Gemini AI Semantic Email Classifier & Auto-Filter Engine.

Summary by CodeRabbit

  • Documentation
    • Added a proposal for a native Gemini-powered semantic Gmail classifier and published end-user setup/behavior documentation.
  • New Features
    • Classifies Gmail threads into 7 canonical domains and applies labels.
    • Creates permanent sender-based Gmail filters when confidence reaches 0.95.
    • Uses a single Processed marker to support safe reprocessing.
  • Bug Fixes
    • Improved handling of Gemini/API failures with stricter validation and transient retry behavior.
  • Tests
    • Expanded unit coverage for validation, retry/exhaustion, and batch processing outcomes.
  • Chores
    • Updated CI/SonarCloud coverage setup and minor workflow/tooling formatting; adjusted dependency overrides.

CodeAnt-AI Description

Add Gemini-powered Gmail classification with automatic labeling, filtering, and GitHub summaries

What Changed

  • Classifies inbox email threads into seven configured domains using sender, subject, and body text, then applies both a domain label and a shared Processed label without removing messages from the Inbox.
  • Creates permanent sender filters for classifications meeting the 95% confidence threshold, while avoiding duplicate filters and handling display-name email addresses.
  • Rejects malformed or unsupported Gemini responses and retries temporary rate-limit and server failures before leaving the thread unchanged.
  • Adds Google Apps Script deployment guidance and GitHub synchronization that can create missing Markdown files, avoid duplicate entries, and retry conflicting updates.
  • Adds automated coverage for classification, labeling, filtering, batch outcomes, retries, GitHub insertion, and scalability scenarios.

Impact

✅ Less manual Gmail sorting
✅ Inbox-preserving email classification
✅ Fewer duplicate sender filters
✅ Fewer unclassified results after temporary API failures

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

@don-petry
don-petry requested a review from a team as a code owner July 28, 2026 01:07
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@codeant-ai

codeant-ai Bot commented Jul 28, 2026

Copy link
Copy Markdown

🤖 CodeAnt AI — Review Status

Status Commit Started (UTC) Finished (UTC)
✅ Incremental review completed 4befa97 Jul 30, 2026 · 03:03 03:03
✅ Incremental review completed 1656f46 Jul 29, 2026 · 23:20 23:20
✅ Incremental review completed f1f8aa1 Jul 29, 2026 · 21:47 21:48
✅ Incremental review completed 64b46ec Jul 29, 2026 · 15:20 15:20
✅ Incremental review completed ee1ae05 Jul 28, 2026 · 20:33 20:33

@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a Gemini-powered Gmail classifier with configurable domains, response validation, retry handling, Gmail labeling, confidence-based filter creation, documentation, tests, coverage reporting, and repository maintenance updates.

Changes

Gmail AI classifier

Layer / File(s) Summary
Classifier configuration and documented workflow
src/gmail-ai-classifier/config.gs, docs/proposals/..., src/gmail-ai-classifier/README.md
Defines Gemini settings, canonical domains, processing labels, confidence thresholds, documented data-handling and reprocessing behavior, and the proposed module layout.
Gemini classification and Gmail automation
src/gmail-ai-classifier/code.gs, src/gmail-ai-classifier/src/index.js
Processes unprocessed threads, calls Gemini with retries, validates responses, applies Gmail labels, and creates qualifying sender filters.
Classifier pipeline validation and coverage
src/gmail-ai-classifier/tests/code.test.js, .github/workflows/sonarcloud.yml, sonar-project.properties
Tests validation, retries, label management, filter behavior, batch outcomes, and LCOV coverage reporting for SonarCloud.

Repository maintenance

Layer / File(s) Summary
Dependency and workflow maintenance
package.json, .github/workflows/*
Adds a brace-expansion override and reformats existing reusable workflow caller definitions without changing their behavior.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Gmail
  participant Classifier
  participant Gemini
  participant AdvancedGmail
  Gmail->>Classifier: Provide unprocessed thread
  Classifier->>Gemini: Submit message details
  Gemini-->>Classifier: Return category and confidence
  Classifier->>Gmail: Apply category and Processed labels
  Classifier->>AdvancedGmail: Create qualifying sender filter
Loading

Possibly related issues

  • petry-projects/google-app-scripts#491 — Directly tracks the Gemini semantic email classifier and self-learning Gmail filter implementation.

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main change: a Gemini-based semantic email classifier proposal with supporting implementation and docs.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/ai-gemini-classifier-proposal

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codeant-ai codeant-ai Bot added the size:M This PR changes 30-99 lines, ignoring generated files label Jul 28, 2026
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Add Proposal 001 for Gemini semantic email classifier + auto-filter engine

📝 Documentation 🕐 Less than 10 minutes

Grey Divider

AI Description

• Add Feature Proposal 001 describing a native Gemini-based email semantic classifier for Gmail
• Outline architecture for Apps Script trigger → Gemini REST call → label/apply actions → optional
 filter creation
• Document proposed module layout, capabilities, and feedback/issue linkage (#491)
Diagram

graph TD
  A(["Incoming email"]) --> B["Apps Script trigger"] --> C{{"Unclassified?"}} --> D["Gemini REST classify"] --> E{{"Confidence >= 95%?"}} --> F["Apply label + actions"] --> G["Create Gmail filter"]
  E -->|"No"| F
  subgraph Legend
    direction LR
    _in(["Input"]) ~~~ _proc["Process"] ~~~ _dec{{"Decision"}}
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Staged rollout (label-only first, filters later)
  • ➕ Reduces risk of creating overly broad/permanent filters from misclassifications
  • ➕ Allows collecting real confidence/precision metrics before modifying user settings
  • ➖ Delayed cost/performance benefit of native Gmail filtering
  • ➖ Requires an explicit second-phase change process
2. Use a curated rules engine first, Gemini as fallback
  • ➕ High precision for common patterns (billing, newsletters) without LLM calls
  • ➕ Less reliance on prompt stability and model drift
  • ➖ Requires ongoing rule maintenance
  • ➖ Lower recall for novel/long-tail senders compared to semantic classification
3. Move automation to Workspace add-on / Cloud Run with Pub/Sub
  • ➕ Event-driven processing (near real-time) and stronger observability/retries
  • ➕ Easier secret management and more robust integration testing
  • ➖ Introduces external infrastructure and operational overhead
  • ➖ Less aligned with the proposal’s “zero external servers” goal

Recommendation: The proposal’s Apps Script + Gemini REST approach is well-aligned with a serverless, repo-native goal. To mitigate irreversible Gmail filter creation risk, consider explicitly specifying a staged rollout: start with classification + labeling/logging, then enable auto-filter generation behind a feature flag or opt-in threshold once precision is validated.

Files changed (1) +71 / -0

Documentation (1) +71 / -0
proposal-001-ai-gemini-semantic-classifier.mdAdd Proposal 001 for Gemini semantic email classifier and auto-filter engine +71/-0

Add Proposal 001 for Gemini semantic email classifier and auto-filter engine

• Introduces a feature proposal detailing a native Google Apps Script module that classifies unprocessed emails via Gemini and optionally creates permanent Gmail filters at high confidence. Includes capability list, a high-level architecture flow, and a proposed repository module structure with tests.

docs/proposals/proposal-001-ai-gemini-semantic-classifier.md

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request proposes a native Gemini AI Semantic Email Classifier & Auto-Filter Engine for the google-app-scripts suite. The feedback suggests aligning the proposed directory structure with the repository layout conventions in AGENTS.md by including a src/index.js file, and replacing LaTeX inline math syntax with standard unicode or plain text for better markdown rendering.

Comment thread docs/proposals/proposal-001-ai-gemini-semantic-classifier.md
Comment thread docs/proposals/proposal-001-ai-gemini-semantic-classifier.md Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/proposals/proposal-001-ai-gemini-semantic-classifier.md`:
- Line 25: Update the fenced code blocks for the architecture diagram and
file-tree sections in the proposal to specify the text language identifier,
using text immediately after each opening fence. Ensure both referenced blocks
are updated without changing their contents.
- Around line 36-38: Expand the classifier response contract in the Gemini
semantic classifier proposal around the “JSON Schema Classification” output:
define the exact response fields and types, permitted labels, confidence meaning
and range, and an explicit abstain/unknown outcome. Document schema validation
and the required behavior for malformed, refused, or invalid responses so filter
creation relies only on validated classifier results.
- Around line 30-31: Update the proposal’s time-driven trigger design to define
bounded batch processing, persisted checkpoints, execution locking, retry
behavior, and an idempotent operation order across Gmail search, classification,
label updates, attachment writes, and log appends. Specify how partial failures
and timeouts resume safely without repeating classifications or duplicating
attachments and logs, using the existing persisted-state flow in code.gs as the
reference pattern.
- Around line 14-19: Expand the proposal’s filter-generation flow around
“Self-Learning Gmail Filter Generation” and the corresponding implementation
details to require calibrated confidence, staged approval or quarantine for
risky senders, duplicate-filter detection, and label existence/resolution
handling before creating sender-wide filters. Define correction semantics so
manual label changes update or delete existing filters, and include rollback
behavior for previously created rules.
- Around line 4-19: Update the proposal’s implementation prerequisites to define
explicit user opt-in configuration, a data-minimization and redaction boundary
for sender, subject, and body content, Gemini provider data-retention
assumptions, API-key storage in user-only Google Apps Script properties, and the
required Gmail Advanced Service/API scopes before implementation.
- Line 6: Update the model identifiers in the proposal’s architecture
description to use one canonical, supported Gemini model, preferably
gemini-1.5-flash-to-250120; alternatively, explicitly document and validate the
fallback strategy for any secondary model. Remove the inconsistent
gemini-2.0-flash reference unless its API compatibility is established.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 2518aa63-6da3-44ec-8f76-c76bdb944bdb

📥 Commits

Reviewing files that changed from the base of the PR and between f61ea03 and 38ead62.

📒 Files selected for processing (1)
  • docs/proposals/proposal-001-ai-gemini-semantic-classifier.md

Comment thread docs/proposals/proposal-001-ai-gemini-semantic-classifier.md Outdated
Comment thread docs/proposals/proposal-001-ai-gemini-semantic-classifier.md Outdated
Comment thread docs/proposals/proposal-001-ai-gemini-semantic-classifier.md Outdated
Comment thread docs/proposals/proposal-001-ai-gemini-semantic-classifier.md
Comment thread docs/proposals/proposal-001-ai-gemini-semantic-classifier.md Outdated
Comment thread docs/proposals/proposal-001-ai-gemini-semantic-classifier.md Outdated
@qodo-code-review

qodo-code-review Bot commented Jul 28, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 20 rules

Grey Divider


Remediation recommended

1. Trailing whitespace in proposal ✓ Resolved 📘 Rule violation ⚙ Maintainability
Description
The new proposal Markdown file includes trailing whitespace on an added line, which violates the
repository’s Prettier formatting expectations and can cause prettier --check to fail (or generate
CI noise) during enforcement.
Code

docs/proposals/proposal-001-ai-gemini-semantic-classifier.md[4]

+This proposal introduces a native **Gemini AI Semantic Email Classifier** module into the `google-app-scripts` suite. 
Relevance

●●● Strong

Team enforces Prettier/whitespace hygiene; accepted removing trailing blank line and formatting
fixes in prior PRs.

PR-#353
PR-#39
PR-#80

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 2237932 requires that changed files within Prettier scope have no Prettier
formatting violations. The proposal file shows a trailing space at the end of the added sentence on
line 4, and the repository’s check script runs prettier --check .; since CI runs `npm run
check`, Prettier will detect and flag this trailing whitespace during the formatting check.

Rule 2237932: No Prettier formatting violations in committed code
docs/proposals/proposal-001-ai-gemini-semantic-classifier.md[4-4]
package.json[5-13]
.prettierignore[1-16]
docs/proposals/proposal-001-ai-gemini-semantic-classifier.md[3-6]
package.json[5-16]
.github/workflows/ci.yml[41-56]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new Markdown proposal contains trailing whitespace on an added line (e.g., line 4). Because the repository enforces formatting via Prettier (run as part of `npm run check`), this can cause `prettier --check .` to report failures/unformatted changes in CI.

## Issue Context
- PR Compliance ID 2237932 requires changed files in Prettier scope to have no Prettier formatting violations.
- The repository’s `check` script runs `prettier --check . && npm run lint`.
- CI runs `npm run check`, so Prettier formatting enforcement will detect trailing whitespace in the changed `.md` file.

## Fix Focus Areas
- docs/proposals/proposal-001-ai-gemini-semantic-classifier.md[4-4]
- package.json[5-16]
- .github/workflows/ci.yml[41-56]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

Comment thread docs/proposals/proposal-001-ai-gemini-semantic-classifier.md Outdated
Comment thread docs/proposals/proposal-001-ai-gemini-semantic-classifier.md Outdated
@donpetry-bot

Copy link
Copy Markdown
Contributor

Advisory bots were rate-limited; auto-approval is withheld until they recover. pr-review-sweep will re-review this PR after 2026-07-28T02:35:42Z.

@codeant-ai codeant-ai Bot added size:L This PR changes 100-499 lines, ignoring generated files and removed size:M This PR changes 30-99 lines, ignoring generated files labels Jul 28, 2026
Comment thread src/gmail-ai-classifier/code.gs Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (4)
src/gmail-ai-classifier/tests/code.test.js (1)

11-11: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Prettier formatting violation.

🎨 Proposed fix
-      canonicalDomains: ['01_Household/Primary_House', '04_Family_Health/Bowens']
+      canonicalDomains: [
+        '01_Household/Primary_House',
+        '04_Family_Health/Bowens',
+      ],
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/gmail-ai-classifier/tests/code.test.js` at line 11, Format the
canonicalDomains array according to the repository’s Prettier rules in the
affected test fixture, preserving both existing domain values and their order.

Source: Linters/SAST tools

src/gmail-ai-classifier/code.gs (2)

80-90: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

Check the HTTP response code before parsing.

muteHttpExceptions: true means non-2xx Gemini responses (rate limits, invalid key, safety blocks) return error bodies without a candidates array, so parsed.candidates[0] throws a generic TypeError that masks the real cause. Checking response.getResponseCode() first would produce a clearer log for troubleshooting auth/quota issues.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/gmail-ai-classifier/code.gs` around lines 80 - 90, Update
classifyWithGemini to check response.getResponseCode() immediately after
UrlFetchApp.fetch and before parsing the body; for non-2xx responses, log the
status and response details, then return null without accessing
parsed.candidates. Preserve the existing parsing flow for successful responses.

29-32: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Threads that fail classification never get labeled and stay in the queue indefinitely.

Since these threads never receive processedLabel, they keep matching config.unprocessedQuery on every future run, permanently occupying a slot in the 15-thread batch. Consider applying a distinct "error"/"unclassified" label so persistently-failing threads don't crowd out new ones.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/gmail-ai-classifier/code.gs` around lines 29 - 32, Update the
classification-failure branch in processEmailsWithAiClassifier to apply a
distinct error or unclassified label to the thread before returning. Reuse the
existing label-management mechanism and preserve the current logging, ensuring
failed threads no longer match config.unprocessedQuery while successfully
classified threads retain their existing labeling flow.
src/gmail-ai-classifier/config.gs (1)

6-7: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Silent placeholder fallback for the API key.

If GEMINI_API_KEY isn't set in Script Properties, this silently falls back to the literal string 'YOUR_GEMINI_API_KEY' rather than failing fast. Every classification call will then fail authentication, but classifyWithGemini's catch-all swallows the error and returns null, so the whole classifier silently no-ops with no clear signal why.

Consider throwing/logging a clear configuration error when the key is missing/placeholder instead of allowing it to propagate silently.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/gmail-ai-classifier/config.gs` around lines 6 - 7, The geminiApiKey
configuration currently accepts a placeholder value and allows authentication
failures to be swallowed by classifyWithGemini. Validate the ScriptProperties
value during configuration, reject missing or placeholder keys with a clear
configuration error, and ensure classifyWithGemini does not silently suppress
this configuration failure.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/gmail-ai-classifier/code.gs`:
- Line 107: Update the success log in createGmailFilterRule to remove
cleanSender from the console.log arguments, while retaining the confirmation
that the permanent Gmail filter was created and the label information.
- Around line 9-21: Update processEmailsWithAiClassifier to sort the threads
returned by GmailApp.search by each thread’s last-message date before the
empty-check and forEach processing flow, using the existing Gmail thread/message
APIs and preserving the current processing behavior after sorting.
- Around line 16-46: Guard both label results from ensureUserLabel before
calling thread.addLabel: validate processedLabel before iterating, and validate
categoryLabel before adding it for each thread. Skip or safely handle the
affected operation when either value is null, while preserving processing of
subsequent threads and the existing behavior for valid labels.
- Around line 95-114: Update createGmailFilterRule to list existing Gmail
filters before calling Gmail.Users.Settings.Filters.create, and skip creation
when a filter already has the same sender criterion and target label action.
Preserve the current filter creation and logging behavior when no matching
filter exists.

In `@src/gmail-ai-classifier/config.gs`:
- Around line 12-16: Update the configuration object so unprocessedQuery is
constructed from the processedLabel value instead of hardcoding “Processed”;
ensure the resulting query continues excluding threads carrying the configured
processed label.

In `@src/gmail-ai-classifier/tests/code.test.js`:
- Around line 5-17: Replace the self-validating literal in the “returns standard
config schema” test with an invocation of the real getAiClassifierConfig
implementation. Export that function through the project’s Node-safe module
boundary (following the existing src/index.js/module.exports pattern), import it
in code.test.js, and inject any required globals through test wrappers so the
assertions validate the actual configuration behavior.

---

Nitpick comments:
In `@src/gmail-ai-classifier/code.gs`:
- Around line 80-90: Update classifyWithGemini to check
response.getResponseCode() immediately after UrlFetchApp.fetch and before
parsing the body; for non-2xx responses, log the status and response details,
then return null without accessing parsed.candidates. Preserve the existing
parsing flow for successful responses.
- Around line 29-32: Update the classification-failure branch in
processEmailsWithAiClassifier to apply a distinct error or unclassified label to
the thread before returning. Reuse the existing label-management mechanism and
preserve the current logging, ensuring failed threads no longer match
config.unprocessedQuery while successfully classified threads retain their
existing labeling flow.

In `@src/gmail-ai-classifier/config.gs`:
- Around line 6-7: The geminiApiKey configuration currently accepts a
placeholder value and allows authentication failures to be swallowed by
classifyWithGemini. Validate the ScriptProperties value during configuration,
reject missing or placeholder keys with a clear configuration error, and ensure
classifyWithGemini does not silently suppress this configuration failure.

In `@src/gmail-ai-classifier/tests/code.test.js`:
- Line 11: Format the canonicalDomains array according to the repository’s
Prettier rules in the affected test fixture, preserving both existing domain
values and their order.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: b9cfa103-3865-4261-8da9-b2bf52ff23e7

📥 Commits

Reviewing files that changed from the base of the PR and between 38ead62 and 8021d5a.

📒 Files selected for processing (5)
  • docs/proposals/proposal-001-ai-gemini-semantic-classifier.md
  • src/gmail-ai-classifier/README.md
  • src/gmail-ai-classifier/code.gs
  • src/gmail-ai-classifier/config.gs
  • src/gmail-ai-classifier/tests/code.test.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/proposals/proposal-001-ai-gemini-semantic-classifier.md

Comment thread src/gmail-ai-classifier/code.gs Outdated
Comment thread src/gmail-ai-classifier/code.gs Outdated
Comment thread src/gmail-ai-classifier/code.gs Outdated
Comment thread src/gmail-ai-classifier/code.gs Outdated
Comment thread src/gmail-ai-classifier/config.gs Outdated
Comment thread src/gmail-ai-classifier/tests/code.test.js Outdated
@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — review-changes (applied)

Changes committed and pushed.

@don-petry
don-petry enabled auto-merge (squash) July 28, 2026 02:48
@don-petry
don-petry disabled auto-merge July 28, 2026 02:49
@github-actions

Copy link
Copy Markdown
Contributor

CI Failure: SonarCloud Code Analysis

Step: SonarCloud Scan (Quality Gate evaluation)
Root cause: Config error

The Quality Gate failed on a single condition: 0.0% Coverage on New Code (required ≥ 80%) for the new src/gmail-ai-classifier/ module. This is not a test failure — tests/code.test.js exists and covers src/index.js — but no coverage report is ever generated or supplied to Sonar. .github/workflows/sonarcloud.yml runs SonarSource/sonarqube-scan-action directly with no prior jest --coverage step, and sonar-project.properties has no sonar.javascript.lcov.reportPaths property pointing at an lcov file, so SonarCloud treats all new lines as uncovered.

Suggested fix: Add a step in sonarcloud.yml to run npm test -- --coverage (producing coverage/lcov.info) before the SonarCloud Scan step, and set sonar.javascript.lcov.reportPaths=coverage/lcov.info in sonar-project.properties.

View run logs

Comment thread src/gmail-ai-classifier/src/index.js
@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — review-changes (applied)

Changes committed and pushed.

@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — review-changes (no-changes)

No changes were needed for this PR.

@donpetry-bot

Copy link
Copy Markdown
Contributor

Advisory bots were rate-limited; auto-approval is withheld until they recover. pr-review-sweep will re-review this PR after 2026-07-29T23:16:21Z.

@donpetry-bot

Copy link
Copy Markdown
Contributor

Advisory bots were rate-limited; auto-approval is withheld until they recover. pr-review-sweep will re-review this PR after 2026-07-29T23:18:53Z.

@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — fix-bot-comment (no-changes)

Agent reasoning
- ✅ Retry-focused tests for `classifyEmailWithGemini` correctly use `jest.useFakeTimers()` and mock sleep functions (lines 455-480, 482-507, 528-561)
- ✅ Timers are properly restored in `finally` blocks
**Code Quality:**
- ✅ All formatting correct (Prettier passes)
- ✅ Lint check passes (only pre-existing warnings in unrelated files)
- ✅ No new code quality issues introduced
### Tier 1 Blocker Status
- ✅ No failed CI checks
- ✅ No CHANGES_REQUESTED reviews (don-petry review is PENDING, awaiting submission)
**Conclusion:** The PR is in excellent shape. The sonarcloud.yml workflow fix has resolved the coverage generation issue, the Quality Gate is passing, all tests pass with strong coverage, and there are no actionable issues blocking merge. The single "1 New issue" flagged by SonarCloud is informational only and doesn't prevent the gate from passing.

@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — review-changes (no-changes)

No changes were needed for this PR.

@donpetry-bot

Copy link
Copy Markdown
Contributor

Advisory bots were rate-limited; auto-approval is withheld until they recover. pr-review-sweep will re-review this PR after 2026-07-29T23:33:22Z.

@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — review-changes (no-changes)

No changes were needed for this PR.

@donpetry-bot

Copy link
Copy Markdown
Contributor

Advisory bots were rate-limited; auto-approval is withheld until they recover. pr-review-sweep will re-review this PR after 2026-07-30T00:22:33Z.

@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — review-changes (no-changes)

No changes were needed for this PR.

@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — review-changes (no-changes)

No changes were needed for this PR.

@donpetry-bot

Copy link
Copy Markdown
Contributor

Advisory bots were rate-limited; auto-approval is withheld until they recover. pr-review-sweep will re-review this PR after 2026-07-30T04:07:09Z.

@donpetry-bot

Copy link
Copy Markdown
Contributor

Advisory bots were rate-limited; auto-approval is withheld until they recover. pr-review-sweep will re-review this PR after 2026-07-30T04:10:10Z.

@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — fix-bot-comment (no-changes)

Agent reasoning
Issues addressed: 0 (bot comment lacks specific issue details; Quality Gate passed)
Files changed: No changes needed
Skipped (informational): Quality Gate passed despite "1 New issue" notation
```

@sonarqubecloud

Copy link
Copy Markdown

@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — review-changes (no-changes)

No changes were needed for this PR.

@donpetry-bot

Copy link
Copy Markdown
Contributor

Advisory bots were rate-limited; auto-approval is withheld until they recover. pr-review-sweep will re-review this PR after 2026-07-30T04:23:45Z.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-human-review size:XXL This PR changes 1000+ lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants