You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Make webhooks the primary ingestion path and retire IMAP safely #299
Requested by @ecarreras after reviewing whether webhook ingestion is ready to become the global default.
Webhook event coverage is already broad, but the fallback IMAP path can still produce a different identity, action, or authorization decision for the same GitHub event. In the audited window for the original two canary repositories:
82 emails were correctly deduplicated against a webhook-created job;
9 distinct work_allowed jobs were created only by IMAP even though webhook had ignored the event or could not correlate it;
This is therefore not just a transport switch. We need one transport-neutral event and authorization contract, evidence that the fallback behaves identically, and a reversible rollout.
Goal
Make GitHub webhooks the authoritative ingestion path for all enabled repositories, keep IMAP temporarily as a deduplicated safety net, and retire the IMAP reader only after two clean observation windows.
The transition must not introduce duplicate jobs, dropped actionable events, reopened work from close/merge notifications, or broader authorization.
Non-goals
Fix the independent OpenClaw session-pruning race or every source of blocked jobs.
Replace the queue or persistence architecture.
Replay historical outside_canary deliveries that may already have been processed by IMAP.
Invariants
The same GitHub event must produce the same canonical identity, action, and work intent regardless of transport or arrival order.
IMAP may cover a missing webhook delivery, but it must never upgrade authorization or reopen completed work.
A close or merge notification must never become open_issue + work_allowed.
Ambiguous or failed classification must fail conservatively to review_only/archive, never retain work_allowed by accident.
Rollout and rollback must be observable, auditable, and possible without losing queued work.
Alert when expected deliveries stop arriving or repeated deliveries fail.
Document the operator runbook and rollback procedure.
7. Promote webhooks and retire IMAP
Set WEBHOOK_MODE=primary and WEBHOOK_PRIMARY_ACK=true only after the promotion gate passes.
Keep IMAP active temporarily as a deduplicated fallback and observe a second stable window.
Verify that IMAP fallback does not create actionable work absent a confirmed webhook delivery gap.
Disable the IMAP reader timer.
Monitor after cutover and keep a tested rollback path for the agreed period.
Remove obsolete IMAP-only code/configuration in a later cleanup PR, not in the cutover itself.
Suggested PR-sized slices
Parity contract and fixtures — normalized envelope plus cross-source regression matrix.
IMAP resolver and canonical identity — issue_event/<id> resolution, action mapping, and deduplication.
Shared authorization guard — one deterministic policy for both transports.
Coverage gate and decision trace — include email:*, expose mismatches, and alert.
Operational hardening — per-owner secrets, hook inspection/ping, monitoring, and runbook.
Primary rollout — configuration change, second observation window, and IMAP timer shutdown.
Slices 2 and 3 depend on the contract in slice 1. Slice 4 must land before promotion. Operational hardening can proceed in parallel with slices 1–4. The final rollout is deliberately separate and should not be bundled with code changes.
Acceptance criteria
Replaying every event in the parity matrix through webhook and IMAP yields the same canonical identity, action, work intent, and work key.
No close or merge fixture can produce open_issue + work_allowed.
The coverage gate includes uncorrelated email receipts and reports zero unexplained actionable IMAP-only events.
The expanded canary completes seven consecutive clean days with zero split jobs and zero authorization mismatches.
Organization-hook delivery inspection, ping, secret rotation, retries, TLS, and missing-delivery alerts are verified and documented.
primary mode completes a second stable observation window with IMAP still deduplicated.
The IMAP reader is disabled without losing or duplicating actionable work, and rollback has been tested/documented.
It updates the README, architecture, ingestion, installation, rollout, operations, scope, failure modes, and agent guide so signed webhooks are documented as a first-class input alongside IMAP. It also keeps the rollout wording conservative: primary is implemented, but IMAP remains the fallback until the parity and observation gates in this issue pass.
This PR references the umbrella and does not close any implementation or cutover acceptance checkbox by itself.
Context
Requested by @ecarreras after reviewing whether webhook ingestion is ready to become the global default.
Webhook event coverage is already broad, but the fallback IMAP path can still produce a different identity, action, or authorization decision for the same GitHub event. In the audited window for the original two canary repositories:
work_allowedjobs were created only by IMAP even though webhook had ignored the event or could not correlate it;#7860and IMAP job#7861; closing the issue later produced IMAP job#7902asopen_issue + work_allowed, while theissues:closedwebhook was correctly ignored;This is therefore not just a transport switch. We need one transport-neutral event and authorization contract, evidence that the fallback behaves identically, and a reversible rollout.
Goal
Make GitHub webhooks the authoritative ingestion path for all enabled repositories, keep IMAP temporarily as a deduplicated safety net, and retire the IMAP reader only after two clean observation windows.
The transition must not introduce duplicate jobs, dropped actionable events, reopened work from close/merge notifications, or broader authorization.
Non-goals
blockedjobs.outside_canarydeliveries that may already have been processed by IMAP.Invariants
open_issue + work_allowed.review_only/archive, never retainwork_allowedby accident.Current state
webhookCanaryReposfrom two to five repositories:gisce/github-agent-bridgegisce/erpgisce/keepupdgisce/oorqgisce/poweremail-modulesDelivery plan
1. Define the cross-source event contract and regression matrix
assigned,closed,merged, review request, issue comment, review comment, and PR review events from both transports.Suggested first slice: tests and contract only, so later implementation PRs have a hard compatibility target.
2. Fix IMAP event resolution and canonical identity
Message-IDvalues such asissue_event/<id>to the actual GitHub event instead of inferring intent from subject/footer text.assigned,closed,merged, review request, and related events through the same mapping used by webhook ingestion.3. Make authorization transport-neutral
X-GitHub-Reason, and email footer text do not authorize work by themselves.4. Repair the coverage gate and expose mismatches
email:*and other currently uncorrelated keys in coverage calculations instead of excluding the problematic population.5. Observe and progressively widen the canary
keepupd,oorq, andpoweremail-modulesto the originalgithub-agent-bridge+erpcanary set.primaryas the mechanism to bypass the canary allowlist.6. Close the organization-hook operational gaps
GITHUB_AGENT_BRIDGE_WEBHOOK_SECRETS_BY_OWNER.admin:org_hook.7. Promote webhooks and retire IMAP
WEBHOOK_MODE=primaryandWEBHOOK_PRIMARY_ACK=trueonly after the promotion gate passes.Suggested PR-sized slices
issue_event/<id>resolution, action mapping, and deduplication.email:*, expose mismatches, and alert.Slices 2 and 3 depend on the contract in slice 1. Slice 4 must land before promotion. Operational hardening can proceed in parallel with slices 1–4. The final rollout is deliberately separate and should not be bundled with code changes.
Acceptance criteria
open_issue + work_allowed.primarymode completes a second stable observation window with IMAP still deduplicated.