ops-inbox: per-draft approval + fact-verified redraft gate#657
ops-inbox: per-draft approval + fact-verified redraft gate#657Aurora Capital (auroracapital) wants to merge 4 commits into
Conversation
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>
There was a problem hiding this comment.
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.
📝 WalkthroughWalkthroughThis 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. ChangesOps-inbox workflow and watcher changes
Estimated code review effort: 4 (Complex) | ~35 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
💡 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. |
There was a problem hiding this comment.
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 👍 / 👎.
| **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. |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
📒 Files selected for processing (1)
claude-ops/skills/ops-inbox/SKILL.md
| 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] | ||
| ``` |
There was a problem hiding this comment.
📐 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.
| 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
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.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 3 potential issues.
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.
| 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) |
There was a problem hiding this comment.
🔒 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.
Reviewed by Cursor Security Reviewer for commit 193db83. Configure here.
There was a problem hiding this comment.
💡 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".
| import json, sys | ||
| seen = set(open('$SEEN').read().split()) | ||
| for t in json.load(sys.stdin): | ||
| if t['id'] not in seen: |
There was a problem hiding this comment.
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 👍 / 👎.
| 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 \ |
There was a problem hiding this comment.
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}\") |
There was a problem hiding this comment.
🔒 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.
Reviewed by Cursor Security Reviewer for commit 41d76e2. Configure here.
There was a problem hiding this comment.
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.
Sent by Cursor Approval Agent: Pull Request Router and Approver
There was a problem hiding this comment.
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 winGuard the empty
ACCT_ARGSexpansion in bothgog gmail searchcalls. On macOS’s stock bash 3.2,"${ACCT_ARGS[@]}"underset -ucan abort when no account is resolved, so this watcher can die before the first poll. Use the empty-array guard pattern or only pass-awhen 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
📒 Files selected for processing (1)
claude-ops/bin/ops-inbox-live-watch.sh
| 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 |
There was a problem hiding this comment.
🎯 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:
- 1: https://gogcli.sh/commands/gog-whoami.html
- 2: https://github.com/openclaw/gogcli/blob/main/docs/commands/gog-whoami.md
- 3: https://gogcli.sh/
- 4: https://github.com/openclaw/gogcli
- 5: https://gogcli.sh/commands/gog-gmail.html
- 6: https://gogcli.sh/quickstart.html
- 7: people me/whoami fails when OAuth client project lacks People API openclaw/gogcli#461
🌐 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:
- 1: https://gogcli.sh/commands/gog-whoami.html
- 2: https://github.com/openclaw/gogcli/blob/main/docs/commands/gog-whoami.md
- 3: https://gogcli.sh/commands/gog.html
- 4: https://gogcli.sh/commands/gog-people-me.html
- 5: https://gogcli.sh/automation.html
- 6: https://gogcli.sh/
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.
| 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; } |
There was a problem hiding this comment.
🩺 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.
| 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.




Summary
ops-inboxnow gets its OWNAskUserQuestion(single-select[Send]/[Edit]/[Skip]), with the chosen option'spreviewfield 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.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]) whosepreviewshows 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
python3 -c "yaml.safe_load(...)")tests/test-no-secrets.shpasses (25/25)/ops:ops-inboxon 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 viagog, polls every ~4 minutes, and exits with aNEW INBOX MAIL: …line when new mail appears (orwatcher expiredafter ~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
AskUserQuestionper draft only ([Send]/[Edit]/[Skip]), with full draft text plus a “Reasoning / facts verified” block inpreview— 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