Skip to content

ops-inbox: per-draft approval + fact-verified redraft gate#657

Open
Aurora Capital (auroracapital) wants to merge 4 commits into
mainfrom
ops-inbox/per-draft-approval-and-fact-gate
Open

ops-inbox: per-draft approval + fact-verified redraft gate#657
Aurora Capital (auroracapital) wants to merge 4 commits into
mainfrom
ops-inbox/per-draft-approval-and-fact-gate

Conversation

@auroracapital

@auroracapital Aurora Capital (auroracapital) commented Jul 4, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Owner directive (2026-07-04): every staged outbound draft in ops-inbox now gets its OWN AskUserQuestion (single-select [Send]/[Edit]/[Skip]), with the chosen option's preview field carrying the FULL draft text plus a short "Reasoning / facts verified" block. Multi-purpose bundled option sets (e.g. [Send] [Edit] [Read full thread] [More...] -> [Archive] [Skip], or [Read + Reply] [Archive] [Skip]) that mixed the send decision with other actions across WhatsApp, iMessage, email, and Notion presentation blocks are replaced with pointers to this new single principle — drafts are never bundled into one omnibus approval.
  • Added a mandatory "Fact-verified redraft gate" (new step 8) to the FULL-CONTEXT / cross-channel dedup section: before staging any draft, the drafter must (a) deep-read the full target thread both directions, (b) read RELATED threads (same contact/topic, cross-channel), and (c) verify every load-bearing factual claim with a cheap check (web search for a price/value, prior threads for who holds what, etc).

Behaviour difference

Before: a NEEDS_REPLY item's draft was shown alongside a multi-option menu (send + edit + read-thread + archive/skip, sometimes behind a [More...] bridge) — functionally a single question mixing several different actions, and nothing in the skill required checking facts in the draft against related threads before it was staged.

After: each draft is staged with exactly one 3-option AskUserQuestion ([Send]/[Edit]/[Skip]) whose preview shows the full draft text plus the reasoning/facts-verified rationale; Archive/Skip-only/Read-full-thread are separate steps, never mixed into the send decision, and never combined across multiple drafts. Before any draft is staged, the drafter must have re-read the target thread, checked related threads, and verified load-bearing facts — preventing failures like routing a master clearance to the wrong label (missed by only reading the target thread) or stating a stale/wrong valuation.

Test plan

  • YAML frontmatter parses (python3 -c "yaml.safe_load(...)")
  • tests/test-no-secrets.sh passes (25/25)
  • Manual dry-run of /ops:ops-inbox on a live inbox (not run here — read-only skill-file edit only, no live inbox touched)

Note

Low Risk
Changes are a read-only polling helper and agent skill documentation; no production send/auth paths are modified in application code.

Overview
Adds bin/ops-inbox-live-watch.sh, a cross-platform background poller that snapshots inbox message IDs via gog, polls every ~4 minutes, and exits with a NEW INBOX MAIL: … line when new mail appears (or watcher expired after ~6h). The ops-inbox skill now requires starting this script at the beginning of every session and treating its exit as a new-mail ping (re-scan + relaunch).

Outbound workflow is tightened in SKILL.md: dedup is explicitly steps 1–7; new mandatory step 8 (fact-verified redraft gate) requires deep-reading the target thread, related threads, and verifying load-bearing facts before staging any draft.

New PER-DRAFT APPROVAL rule: one AskUserQuestion per draft only ([Send] / [Edit] / [Skip]), with full draft text plus a “Reasoning / facts verified” block in preview — no bundled multi-recipient approvals and no mixing send with archive/read-thread/[More…] menus. Email, WhatsApp, iMessage, and Notion sections are updated to match.

Reviewed by Cursor Bugbot for commit 41d76e2. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

  • New Features
    • Added a live inbox watcher that periodically polls Gmail for new inbound messages and triggers a refresh when detected.
  • Bug Fixes
    • Enforced a blocking dedup step before confirming replies to prevent duplicate processing across threads and channels.
    • Added a fact-verified redraft gate that re-checks the relevant context before drafting.
    • Tightened approvals to use one-at-a-time Send/Edit/Skip decisions with a standardized preview per draft.
  • Documentation
    • Updated channel-specific guidance for email and Notion reply controls to match the new one-at-a-time flow.

Owner directive (2026-07-04): replace any bundled/omnibus draft-approval
menus with one AskUserQuestion per draft (single-select [Send]/[Edit]/[Skip],
preview = full draft text + a "Reasoning / facts verified" block), and add a
mandatory fact-verified redraft gate to the FULL-CONTEXT/dedup section:
before staging any draft, deep-read the target thread both directions, read
related threads (same contact/topic across channels), and verify every
load-bearing factual claim with a cheap check.

Behaviour before: presentation blocks (WhatsApp, iMessage, email, Notion)
showed a draft alongside multi-purpose option sets (e.g. [Send] [Edit]
[Read full thread] [More...] -> [Archive] [Skip]) that mixed the send
decision with other actions, and nothing required verifying draft facts
against related threads before staging.

Behaviour after: every draft gets its own 3-option AskUserQuestion whose
preview carries the full text plus verified reasoning; Archive/Skip/Read
are handled as separate steps outside the send question; a new numbered
step 8 in the dedup gate blocks staging until related threads are read and
load-bearing facts (e.g. rights ownership, a valuation) are verified.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@claude claude 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 skipped — your organization's overage spend limit has been reached.

Code review is billed via overage credits. To resume reviews, an organization admin can raise the monthly limit at claude.ai/admin-settings/claude-code.

Once credits are available, push a new commit or reopen this pull request to trigger a review.

@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR tightens ops-inbox draft gating and channel-specific approval wording, and adds a background Gmail watcher that detects new inbound mail and exits when it fires.

Changes

Ops-inbox workflow and watcher changes

Layer / File(s) Summary
Workflow gates and per-draft approval
claude-ops/skills/ops-inbox/SKILL.md
Adds a background inbox watcher hook, a blocking dedup gate, a fact-verified redraft gate, and stricter single-draft approval rules across NEEDS_REPLY, WhatsApp, iMessage, Email, and Notion.
Gmail live watcher script
claude-ops/bin/ops-inbox-live-watch.sh
Adds a Bash script that loads optional secrets, validates prerequisites, seeds seen Gmail message IDs, polls for new mail, and exits when a new inbox message appears or the watch window expires.

Estimated code review effort: 4 (Complex) | ~35 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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 clearly captures the two main changes: per-draft approval and the fact-verified redraft gate.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ops-inbox/per-draft-approval-and-fact-gate

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.

@cursor cursor 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.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Autofix Details

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Step eight requires draft first
    • Separated the pre-classification dedup gate (steps 1–7) from the post-draft fact-verified redraft gate (step 8) so drafting precedes claim verification and staging.

You can send follow-ups to the cloud agent here.

Comment thread claude-ops/skills/ops-inbox/SKILL.md

@cursor cursor 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.

Stale comment

Not approving: Cursor Bugbot completed as skipped and reported 1 potential issue (step 8 ordering vs draft staging). Human review is needed before merge.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router and Approver

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 073bd82a43

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "Codex (@codex) review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".

Only after steps 1–6 ALL come up empty is a thread a true NEEDS_REPLY. This is the FULL-THREAD AWARENESS GATE, extended cross-channel and cross-request. **Surfacing a NEEDS_REPLY without having run the cross-thread, cross-channel, cross-request, and already-sent searches is a scan bug — do not present it.** None of this changes the outbound path: even a genuine NEEDS_REPLY is still drafted and sent only in the main session under the Rule-6 one-draft → one-approval → one-send gate.
**The call, exactly:**

- **Single-select**, options limited to `[Send]` `[Edit]` `[Skip]` (3 options — well under the Rule-1 cap of 4). Do not add extra options like "Read full thread" or "Archive" to this specific question — the full-thread read is already mandatory *before* the draft is staged (FULL-THREAD AWARENESS GATE + fact-verified redraft gate above), and archive is a separate, subsequent step once the draft is sent or skipped.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve the email tracking approval path

For email replies where open tracking is configured, this new global rule forbids any send-approval option beyond [Send]/[Edit]/[Skip], but the existing Open Tracking section still requires surfacing [Send + track opens] in the same send-approval AskUserQuestion. An ops-inbox run that follows the new rule can no longer offer the documented opt-in --track path, while adding it would violate this rule; please reconcile the two flows, e.g. by defining a separate tracking opt-in step or explicitly allowing the fourth option for email tracking.

Useful? React with 👍 / 👎.

Comment on lines +700 to +704
**Every staged outbound draft gets its OWN `AskUserQuestion` call — never bundle multiple drafts into one question, and never present a batched list of drafts with an "approve all" / "ok all" style option.** This applies on every channel (email, WhatsApp, iMessage, Slack, Telegram, Discord, Notion) and supersedes any earlier guidance in this skill that showed multiple candidates followed by a single combined approval.

Only after steps 1–6 ALL come up empty is a thread a true NEEDS_REPLY. This is the FULL-THREAD AWARENESS GATE, extended cross-channel and cross-request. **Surfacing a NEEDS_REPLY without having run the cross-thread, cross-channel, cross-request, and already-sent searches is a scan bug — do not present it.** None of this changes the outbound path: even a genuine NEEDS_REPLY is still drafted and sent only in the main session under the Rule-6 one-draft → one-approval → one-send gate.
**The call, exactly:**

- **Single-select**, options limited to `[Send]` `[Edit]` `[Skip]` (3 options — well under the Rule-1 cap of 4). Do not add extra options like "Read full thread" or "Archive" to this specific question — the full-thread read is already mandatory *before* the draft is staged (FULL-THREAD AWARENESS GATE + fact-verified redraft gate above), and archive is a separate, subsequent step once the draft is sent or skipped.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: The new PER-DRAFT APPROVAL principle (3 options) conflicts with the existing Open Tracking section, which still shows 4 options, making open-tracking inaccessible.
Severity: MEDIUM

Suggested Fix

Update the Open Tracking section in SKILL.md to align with the new PER-DRAFT APPROVAL principle. This could involve removing the [Send + track opens] option from the main approval prompt and finding an alternative way to offer this functionality that does not violate the three-option limit.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: claude-ops/skills/ops-inbox/SKILL.md#L700-L704

Potential issue: The newly introduced `PER-DRAFT APPROVAL` principle limits user
response options in draft approvals to three: `[Send]`, `[Edit]`, and `[Skip]`. However,
the existing `Open Tracking` section was not updated and still instructs the agent to
present four options, including `[Send + track opens]`. This creates a contradiction in
the skill's instructions. An agent following the new three-option rule would make the
opt-in email open-tracking feature inaccessible, while an agent following the `Open
Tracking` section would violate the new principle.

Did we get this right? 👍 / 👎 to inform future reviews.

…step 8

Split the pre-classification dedup gate (steps 1-7) from the post-draft
fact-verified redraft gate (step 8) so agents draft before verifying
load-bearing claims, not before a draft exists.

@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: 1

🤖 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 `@claude-ops/skills/ops-inbox/SKILL.md`:
- Around line 1218-1225: The example block in SKILL.md is missing a language
tag, which causes markdownlint MD040 and makes the template look executable.
Update the fenced example under the PER-DRAFT APPROVAL guidance to use a plain
text fence on the block that shows the AskUserQuestion preview and buttons, so
the snippet remains clearly non-code while preserving the existing Reply to
[Sender] — [Subject] example content.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4d6c171b-8203-4cdd-b08c-b45fa67868c2

📥 Commits

Reviewing files that changed from the base of the PR and between 0122411 and 073bd82.

📒 Files selected for processing (1)
  • claude-ops/skills/ops-inbox/SKILL.md

Comment on lines +1218 to 1225
Per the **PER-DRAFT APPROVAL** principle above: stage ONE `AskUserQuestion` per email, single-select — never a combined `[Read + Reply]`/`[Archive]`/`[Skip]` menu that mixes the send decision with other actions. The question's `preview` field carries the FULL draft text (to, subject, body) plus a short "Reasoning / facts verified" block (which thread(s) and related threads were read, which facts were checked):

```
Reply to [Sender] — [Subject]:
"[drafted reply]"
preview: "[FULL drafted reply text]\n\nReasoning / facts verified: [thread(s) read, related threads checked, facts verified and how]"

[Send] [Edit] [Skip]
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Tag the example block as plain text.

The unlabelled fence trips markdownlint (MD040) and makes this template look executable.

🛠️ Proposed fix
-```
+```text
 Reply to [Sender] — [Subject]:
   preview: "[FULL drafted reply text]\n\nReasoning / facts verified: [thread(s) read, related threads checked, facts verified and how]"
 
   [Send]  [Edit]  [Skip]
-```
+```
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Per the **PER-DRAFT APPROVAL** principle above: stage ONE `AskUserQuestion` per email, single-select — never a combined `[Read + Reply]`/`[Archive]`/`[Skip]` menu that mixes the send decision with other actions. The question's `preview` field carries the FULL draft text (to, subject, body) plus a short "Reasoning / facts verified" block (which thread(s) and related threads were read, which facts were checked):
```
Reply to [Sender][Subject]:
"[drafted reply]"
preview: "[FULL drafted reply text]\n\nReasoning / facts verified: [thread(s) read, related threads checked, facts verified and how]"
[Send] [Edit] [Skip]
```
Per the **PER-DRAFT APPROVAL** principle above: stage ONE `AskUserQuestion` per email, single-select — never a combined `[Read + Reply]`/`[Archive]`/`[Skip]` menu that mixes the send decision with other actions. The question's `preview` field carries the FULL draft text (to, subject, body) plus a short "Reasoning / facts verified" block (which thread(s) and related threads were read, which facts were checked):
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 1220-1220: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🪛 SkillSpector (2.3.7)

[error] 768: [AS1] Agent Config Directory Access: Skill reads from agent configuration directories (.claude/, .codex/, .gemini/). These directories may contain API keys, personal settings, and other credentials that the skill has no legitimate need to access.

Remediation: Remove all code or instructions that access agent configuration directories (.claude/, .codex/, .gemini/). If configuration values are needed, pass them explicitly as parameters or environment variables — never read the agent's own config files.

(Agent Snooping (AS1))


[warning] 1450: [AS3] Skill Enumeration: Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Remediation: Remove all code or instructions that list or read other skills' files or directories. Skills should operate independently; cross-skill access is a privilege escalation.

(Agent Snooping (AS3))


[warning] 772: [E1] External Transmission: Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Remediation: Verify the destination URL is trusted and necessary. Remove or replace with documented APIs. Ensure no secrets, tokens, or PII are transmitted.

(Data Exfiltration (E1))


[warning] 733: [EA2] Autonomous Decision Making: Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Remediation: Add human-in-the-loop confirmation for destructive, irreversible, or high-impact operations. Never auto-execute commands that modify files, send data, or alter system state.

(Excessive Agency (EA2))


[warning] 735: [EA2] Autonomous Decision Making: Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Remediation: Add human-in-the-loop confirmation for destructive, irreversible, or high-impact operations. Never auto-execute commands that modify files, send data, or alter system state.

(Excessive Agency (EA2))


[warning] 66: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 68: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 69: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 70: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 71: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 72: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 225: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 225: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 227: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 229: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 229: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 230: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 231: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 231: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 232: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 278: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 278: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 280: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 281: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 282: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 282: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 283: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 283: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 285: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 286: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 287: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 288: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 290: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 290: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 291: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 292: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 293: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 293: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 553: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 553: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 555: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 556: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 557: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 558: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 1009: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 1011: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 1012: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 1013: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 1014: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 1015: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 1016: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 1017: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 1018: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 1019: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 1021: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 1022: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 1104: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 1106: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 1111: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 1127: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[error] 1140: [OH1] Unvalidated Output Injection: Model output is used without validation or sanitization. Unvalidated output injected into downstream contexts (SQL, shell, HTML) enables injection attacks and arbitrary code execution.

Remediation: Validate and sanitize all model output before using it in downstream contexts. Use parameterized queries for SQL, shell quoting for commands, and HTML encoding for web output.

(Output Handling (OH1))


[warning] 13: [RA2] Session Persistence: Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Remediation: Remove any persistence mechanisms (cron jobs, startup scripts, state files). Skills should not maintain state across sessions without explicit user consent.

(Rogue Agent (RA2))


[warning] 897: [RA2] Session Persistence: Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Remediation: Remove any persistence mechanisms (cron jobs, startup scripts, state files). Skills should not maintain state across sessions without explicit user consent.

(Rogue Agent (RA2))


[warning] 1045: [RA2] Session Persistence: Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Remediation: Remove any persistence mechanisms (cron jobs, startup scripts, state files). Skills should not maintain state across sessions without explicit user consent.

(Rogue Agent (RA2))


[warning] 196: [RA2] Session Persistence: Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Remediation: Remove any persistence mechanisms (cron jobs, startup scripts, state files). Skills should not maintain state across sessions without explicit user consent.

(Rogue Agent (RA2))


[warning] 196: [RA2] Session Persistence: Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Remediation: Remove any persistence mechanisms (cron jobs, startup scripts, state files). Skills should not maintain state across sessions without explicit user consent.

(Rogue Agent (RA2))


[warning] 196: [RA2] Session Persistence: Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Remediation: Remove any persistence mechanisms (cron jobs, startup scripts, state files). Skills should not maintain state across sessions without explicit user consent.

(Rogue Agent (RA2))


[warning] 767: [RA2] Session Persistence: Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Remediation: Remove any persistence mechanisms (cron jobs, startup scripts, state files). Skills should not maintain state across sessions without explicit user consent.

(Rogue Agent (RA2))


[warning] 770: [RA2] Session Persistence: Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Remediation: Remove any persistence mechanisms (cron jobs, startup scripts, state files). Skills should not maintain state across sessions without explicit user consent.

(Rogue Agent (RA2))


[warning] 770: [RA2] Session Persistence: Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Remediation: Remove any persistence mechanisms (cron jobs, startup scripts, state files). Skills should not maintain state across sessions without explicit user consent.

(Rogue Agent (RA2))


[warning] 770: [RA2] Session Persistence: Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Remediation: Remove any persistence mechanisms (cron jobs, startup scripts, state files). Skills should not maintain state across sessions without explicit user consent.

(Rogue Agent (RA2))


[warning] 770: [RA2] Session Persistence: Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Remediation: Remove any persistence mechanisms (cron jobs, startup scripts, state files). Skills should not maintain state across sessions without explicit user consent.

(Rogue Agent (RA2))


[warning] 1026: [RA2] Session Persistence: Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Remediation: Remove any persistence mechanisms (cron jobs, startup scripts, state files). Skills should not maintain state across sessions without explicit user consent.

(Rogue Agent (RA2))

🤖 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 `@claude-ops/skills/ops-inbox/SKILL.md` around lines 1218 - 1225, The example
block in SKILL.md is missing a language tag, which causes markdownlint MD040 and
makes the template look executable. Update the fenced example under the
PER-DRAFT APPROVAL guidance to use a plain text fence on the block that shows
the AskUserQuestion preview and buttons, so the snippet remains clearly non-code
while preserving the existing Reply to [Sender] — [Subject] example content.

Source: Linters/SAST tools

cursor[bot]
cursor Bot approved these changes Jul 4, 2026
Ports the ad-hoc inbox-live-watch hook into the plugin proper: bin/ops-inbox-live-watch.sh
polls Gmail via gog every ~4min and exits with a NEW INBOX MAIL summary line the instant a
new inbound message lands (or "watcher expired" after ~6h). Pure bash + python3 + gog, no
systemd/launchd dependency, $TMPDIR-safe seen-file — works unchanged on Linux and macOS.

SKILL.md Runtime Context now launches it as a background job at the start of every
ops-inbox session; its exit is treated as a direct new-mail ping, and it is relaunched
after each ping so live coverage never lapses.

@cursor cursor 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.

Cursor Bugbot has reviewed your changes using default effort and found 3 potential issues.

Fix All in Cursor

Bugbot Autofix prepared fixes for all 3 issues found in the latest run.

  • ✅ Fixed: Watcher ignores Gmail account
    • Added GMAIL_ACCOUNT/GOG_ACCOUNT resolution with gog whoami fallback and pass -a via ACCT_ARGS on all gog gmail search calls, matching ops-inbox-scan.
  • ✅ Fixed: Top fifteen baseline false alerts
    • Baseline now snapshots up to 100 inbox IDs and each poll refreshes the seen set when no new mail is found, so older threads re-entering the top 15 no longer trigger false alerts.
  • ✅ Fixed: Empty baseline false new mail
    • Baseline gog/json failures now exit 2 with an error message instead of entering the poll loop with an empty seen set.

You can send follow-ups to the cloud agent here.

Reviewed by Cursor Bugbot for commit 193db83. Configure here.

Comment thread claude-ops/bin/ops-inbox-live-watch.sh Outdated
Comment thread claude-ops/bin/ops-inbox-live-watch.sh Outdated
Comment thread claude-ops/bin/ops-inbox-live-watch.sh

@cursor cursor 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.

Stale comment

Comment thread claude-ops/bin/ops-inbox-live-watch.sh Outdated
seen = set(open('$SEEN').read().split())
for t in json.load(sys.stdin):
if t['id'] not in seen:
print(f\"NEW INBOX MAIL: {t['from']} | {t['subject']} | {t['date']} | id={t['id']}\")" 2>/dev/null)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Agentic Security Review
Severity: MEDIUM

The watcher prints untrusted email metadata (from, subject, date) directly to stdout as part of the NEW INBOX MAIL signal. Because these fields are attacker-controlled by an inbound sender, this creates an injection-prone/log-leaking boundary where external content is emitted into automation/terminal logs without sanitization.

Impact: Sensitive communication metadata can be exposed in logs, and attacker-crafted subject/display-name text can propagate into downstream automation contexts that consume this signal line.

Fix in Cursor Fix in Web

Reviewed by Cursor Security Reviewer for commit 193db83. Configure here.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 193db83f71

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "Codex (@codex) review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".

Comment thread claude-ops/bin/ops-inbox-live-watch.sh Outdated
import json, sys
seen = set(open('$SEEN').read().split())
for t in json.load(sys.stdin):
if t['id'] not in seen:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Track actual new messages instead of thread membership

The watcher snapshots only the first 15 thread IDs and later treats any ID not in that fixed set as new. In an ops-inbox run with more than 15 inbox threads, archiving/processing any of the initial 15 exposes an older existing thread and emits a false NEW INBOX MAIL; conversely, a new reply on a thread already present at startup keeps the same thread ID and is never reported. Track a startup high-water mark (message date/message id) or refresh the seen set, rather than comparing only thread IDs.

Useful? React with 👍 / 👎.

Comment thread claude-ops/bin/ops-inbox-live-watch.sh Outdated
SEEN="$(mktemp "${TMPDIR:-/tmp}/.ops-inbox-seen-ids.XXXXXX")"
trap 'rm -f "$SEEN"' EXIT

gog gmail search "in:inbox" --max 15 -j --results-only --no-input 2>/dev/null \

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Honor the inbox account used by the scan

ops-inbox documents and uses GMAIL_ACCOUNT for gog scans (the main scanner passes it as -a), but this new watcher calls gog gmail search without any account args and only relies on gog's default/GOG_ACCOUNT. In a multi-account session pinned with GMAIL_ACCOUNT, the scan and live watcher can monitor different mailboxes, so new-mail pings are missed or generated for the wrong account; build the same account args for both search calls.

Useful? React with 👍 / 👎.

- Pass -a with GMAIL_ACCOUNT/GOG_ACCOUNT (auto-detect via gog whoami)
- Snapshot top 100 inbox IDs at startup and refresh seen set each poll
- Exit with error when baseline gog snapshot fails instead of polling blind
for t in data:
tid = t['id']
if tid not in seen:
new_lines.append(f\"NEW INBOX MAIL: {t['from']} | {t['subject']} | {t['date']} | id={tid}\")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Agentic Security Review
Severity: MEDIUM
The watcher emits untrusted inbound email metadata (from, subject, date) directly in the machine signal line (NEW INBOX MAIL: ...) without sanitization or structured encoding. This allows attacker-controlled content to flow into terminal/log/automation consumers of that signal.

Impact: Crafted subject/display-name values can poison downstream parsing and expose sensitive message metadata in shared logs.

Fix in Cursor Fix in Web

Reviewed by Cursor Security Reviewer for commit 41d76e2. Configure here.

@cursor cursor 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.

Not approving: Cursor Bugbot passed on the latest commit with all Bugbot threads resolved, but the Security Reviewer left an unresolved MEDIUM finding (unsanitized email metadata in the watcher signal line) and there are unresolved PER-DRAFT APPROVAL vs Open Tracking conflicts. Human review is needed before merge.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router and Approver

@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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
claude-ops/bin/ops-inbox-live-watch.sh (1)

18-18: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Guard the empty ACCT_ARGS expansion in both gog gmail search calls. On macOS’s stock bash 3.2, "${ACCT_ARGS[@]}" under set -u can abort when no account is resolved, so this watcher can die before the first poll. Use the empty-array guard pattern or only pass -a when the array is non-empty.

🤖 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 `@claude-ops/bin/ops-inbox-live-watch.sh` at line 18, The
`ops-inbox-live-watch.sh` watcher can abort under `set -u` when `ACCT_ARGS` is
empty, so update both `gog gmail search` invocations to use a safe empty-array
expansion pattern or conditionally add the `-a` argument only when an account
was resolved. Keep the fix localized around the `ACCT_ARGS` handling in the
script so the poll loop continues even when no account is found.
🤖 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 `@claude-ops/bin/ops-inbox-live-watch.sh`:
- Around line 28-31: The account lookup in ops-inbox-live-watch.sh is relying on
human-readable `gog whoami` output and `head -1`, which is not a stable
contract. Update the fallback logic around `GMAIL_ACCOUNT` to use structured
output from `gog whoami` (prefer `--json` with `jq -r '.email'`, or `--plain` if
supported) so the email is extracted reliably regardless of output formatting.
Keep the existing `GMAIL_ACCOUNT`/`GOG_ACCOUNT` flow and replace the parsing in
the `gog whoami` fallback path only.
- Around line 47-63: The per-iteration poll in ops-inbox-live-watch.sh currently
treats gog gmail search and the embedded python3 JSON parsing failures as “no
new mail,” so the watcher can silently mask broken polling. Update the polling
logic around the NEW assignment to capture the command’s exit status and stderr,
and if either gog or the python script fails, emit a clear error and exit
non-zero instead of continuing; use the existing baseline pipeline error
handling pattern in the script as a guide.

---

Outside diff comments:
In `@claude-ops/bin/ops-inbox-live-watch.sh`:
- Line 18: The `ops-inbox-live-watch.sh` watcher can abort under `set -u` when
`ACCT_ARGS` is empty, so update both `gog gmail search` invocations to use a
safe empty-array expansion pattern or conditionally add the `-a` argument only
when an account was resolved. Keep the fix localized around the `ACCT_ARGS`
handling in the script so the poll loop continues even when no account is found.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7aaae06f-ccc9-4fae-9bf8-b528c211d326

📥 Commits

Reviewing files that changed from the base of the PR and between 193db83 and 41d76e2.

📒 Files selected for processing (1)
  • claude-ops/bin/ops-inbox-live-watch.sh

Comment on lines +28 to +31
GMAIL_ACCOUNT="${GMAIL_ACCOUNT:-${GOG_ACCOUNT:-}}"
if [ -z "$GMAIL_ACCOUNT" ]; then
GMAIL_ACCOUNT="$(gog whoami 2>/dev/null | head -1 | grep -oE '[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+' || true)"
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

What is the stdout format of gog whoami in the gog Gmail CLI — does it print the account email on the first line?

💡 Result:

The gog CLI command gog whoami is designed to display information about the currently authenticated user [1][2]. Its standard output format depends on the output flags provided: When used without format flags, it typically outputs human-readable profile information, which includes the account email address. When used with the --json flag, the command outputs a structured JSON object to stdout containing the user's profile details [3][4][5]. When used with the --plain flag, it outputs the information in a stable, parseable text format (TSV) [4][5]. In standard human-readable mode, the account email is typically displayed as part of the profile summary, often on the first line or prominently within the output. However, because gog prioritizes keeping stdout parseable for scripts and automation, users are encouraged to use --json or --plain for consistent programmatic access to the email address rather than parsing the default human-readable stdout [3][4][6]. Note that gog whoami relies on the People API; if this API is not enabled in the OAuth client project, the command may fail [7].

Citations:


🌐 Web query:

gog whoami output example email first line stable parseable text format docs

💡 Result:

In the context of the gog CLI tool, gog whoami (which is an alias for gog people me) does not provide a fixed, stable parseable plain text output format that is guaranteed to start with an email address on the first line [1][2][3]. The gog CLI provides stable, machine-readable output primarily through the --json flag [4][5][6]. For scripting and automation, the recommended practice is to use: gog whoami --json This command returns a structured JSON object. The tool design explicitly uses --json for structured output and --plain for stable TSV (tab-separated values) output, rather than relying on unstructured text parsing [5][6]. If you are attempting to extract an email address, you should parse the JSON output using a tool like jq: gog whoami --json | jq -r '.email' The gog documentation emphasizes that for automation, you should rely on the --json flag or --plain (TSV) mode, as the default interactive output is intended for human consumption and may change [5][6]. Relying on the first line of the default standard output is not considered a stable automation contract [5].

Citations:


Parse gog whoami as JSON instead of head -1.
The default human-readable output isn’t a stable automation contract, so the email can be missed if it doesn’t appear on line 1. Use gog whoami --json | jq -r '.email' (or --plain if that’s already supported here) to make account detection reliable.

🤖 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 `@claude-ops/bin/ops-inbox-live-watch.sh` around lines 28 - 31, The account
lookup in ops-inbox-live-watch.sh is relying on human-readable `gog whoami`
output and `head -1`, which is not a stable contract. Update the fallback logic
around `GMAIL_ACCOUNT` to use structured output from `gog whoami` (prefer
`--json` with `jq -r '.email'`, or `--plain` if supported) so the email is
extracted reliably regardless of output formatting. Keep the existing
`GMAIL_ACCOUNT`/`GOG_ACCOUNT` flow and replace the parsing in the `gog whoami`
fallback path only.

Comment on lines +47 to +63
NEW=$(gog gmail search "${ACCT_ARGS[@]}" "in:inbox" --max 15 -j --results-only --no-input | python3 -c "
import json, sys
seen = set(open('$SEEN').read().split())
data = json.load(sys.stdin)
new_lines = []
for t in data:
tid = t['id']
if tid not in seen:
new_lines.append(f\"NEW INBOX MAIL: {t['from']} | {t['subject']} | {t['date']} | id={tid}\")
seen.add(tid)
if not new_lines:
with open('$SEEN', 'w') as f:
if seen:
f.write('\n'.join(seen) + '\n')
for line in new_lines:
print(line)")
[ -n "$NEW" ] && { echo "$NEW"; exit 0; }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Polling loop silently swallows gog/python failures.

Unlike the baseline snapshot (Lines 38-43), which checks the pipeline's exit status and logs stderr on failure, the per-iteration poll at Line 47 has no error check at all: if gog gmail search fails (auth expiry, network blip, rate limit) or the python3 JSON parse throws, $NEW is simply empty and the loop treats it identically to "no new mail." Over the ~6h window this can silently mask a broken watcher, and it will eventually print "watcher expired... no new mail" even though polling was never actually working — giving the orchestrator false assurance per the "job's exit IS the new-mail ping" contract in SKILL.md.

🩹 Proposed fix: capture and surface poll failures
-  NEW=$(gog gmail search "${ACCT_ARGS[@]}" "in:inbox" --max 15 -j --results-only --no-input | python3 -c "
+  if ! NEW=$(gog gmail search "${ACCT_ARGS[@]}" "in:inbox" --max 15 -j --results-only --no-input 2>"${SEEN}.err" | python3 -c "
...
")"; then
+    echo "ops-inbox-live-watch: poll #$i failed: $(head -c 200 "${SEEN}.err" 2>/dev/null | tr '\n' ' ')" >&2
+  fi
   [ -n "$NEW" ] && { echo "$NEW"; exit 0; }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
NEW=$(gog gmail search "${ACCT_ARGS[@]}" "in:inbox" --max 15 -j --results-only --no-input | python3 -c "
import json, sys
seen = set(open('$SEEN').read().split())
data = json.load(sys.stdin)
new_lines = []
for t in data:
tid = t['id']
if tid not in seen:
new_lines.append(f\"NEW INBOX MAIL: {t['from']} | {t['subject']} | {t['date']} | id={tid}\")
seen.add(tid)
if not new_lines:
with open('$SEEN', 'w') as f:
if seen:
f.write('\n'.join(seen) + '\n')
for line in new_lines:
print(line)")
[ -n "$NEW" ] && { echo "$NEW"; exit 0; }
if ! NEW=$(gog gmail search "${ACCT_ARGS[@]}" "in:inbox" --max 15 -j --results-only --no-input 2>"${SEEN}.err" | python3 -c "
import json, sys
seen = set(open('$SEEN').read().split())
data = json.load(sys.stdin)
new_lines = []
for t in data:
tid = t['id']
if tid not in seen:
new_lines.append(f\"NEW INBOX MAIL: {t['from']} | {t['subject']} | {t['date']} | id={tid}\")
seen.add(tid)
if not new_lines:
with open('$SEEN', 'w') as f:
if seen:
f.write('\n'.join(seen) + '\n')
for line in new_lines:
print(line)"); then
echo "ops-inbox-live-watch: poll #$i failed: $(head -c 200 "${SEEN}.err" 2>/dev/null | tr '\n' ' ')" >&2
fi
[ -n "$NEW" ] && { echo "$NEW"; exit 0; }
🤖 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 `@claude-ops/bin/ops-inbox-live-watch.sh` around lines 47 - 63, The
per-iteration poll in ops-inbox-live-watch.sh currently treats gog gmail search
and the embedded python3 JSON parsing failures as “no new mail,” so the watcher
can silently mask broken polling. Update the polling logic around the NEW
assignment to capture the command’s exit status and stderr, and if either gog or
the python script fails, emit a clear error and exit non-zero instead of
continuing; use the existing baseline pipeline error handling pattern in the
script as a guide.

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.

2 participants