Skip to content

ADR-047: operator skip rules - #561

Merged
hardbyte merged 3 commits into
mainfrom
ccr-37ca53f6-xza211-adr-skip-rules
Nov 8, 2026
Merged

hardbyte merged 3 commits into
mainfrom
ccr-37ca53f6-xza211-adr-skip-rules

Conversation

@hardbyte

@hardbyte hardbyte commented Oct 27, 2026 •

Copy link
Copy Markdown
Owner

Proposes ADR-047, operator skip rules. An operator can stop jobs of one kind from running, optionally only those whose args match a CEL predicate, without pausing the queue or deploying. This follows on from the poison-job work in #546, which bounded a poison job's damage, and this PR is docs only.

The gap

Today an operator's controls are:

  • Queue pause: stops every kind on the queue.
  • Batch operations: only reach jobs that already exist.
  • DLQ actions: apply after the damage is done.
  • A flag in the handler: needs a deploy.

The docs answer "stop a kind" with "put it on its own queue", which only works if the queue layout anticipated the problem.

The decision

  • Rules table: awa.job_skip_rules has a required kind, an optional queue, an optional CEL expression, an action, a reason, an expiry and audit columns. Operators write it rarely and nothing on the job path writes it, so it is not a hot table.

  • When rules apply: the worker checks rules after it claims a job and before the handler runs. Rules reach workers on the 10-second refresh that ADR-038 queue overrides already use. Expressions are compiled once per refresh. A kind with no rules costs one hash lookup.

  • Actions reuse existing paths, so no new state is introduced:

    • hold (the default) snoozes the job without spending an attempt, until the rule expires or for 24 hours, whichever is sooner. Removing the rule releases its held jobs in one batch operation. A short hold interval would re-claim every held job each cycle; holding to the horizon avoids that.
    • dead_letter sends the job to the DLQ with reason skipped.
    • cancel cancels the job.

    Hooks and registered follow-ups fire as if the handler had returned that result.

  • CEL: expressions can read args, metadata, kind, queue, attempt, priority and tags. An expression that errors at evaluation does not match, so a bad rule cannot quarantine healthy jobs. Each error is counted per rule.

  • Operator surface:

    • awa job skip add / list / remove;
    • a preview that narrows by kind, queue and state in SQL and then evaluates the expression on at most 10,000 rows;
    • an admin UI list of rules;
    • metrics, including a held-jobs gauge per rule.
  • Phasing: phase 1 matches by kind and queue only. Phase 2 adds expressions, gated by the existing cel feature.

Why it doesn't go against the grain

  • Claim path: rules apply after the claim, so the claim query is untouched. ADR-033 rules out skipping rows at claim time because doing so breaks the cursor and prune proofs.
  • CEL: rules evaluate one job at a time, the use ADR-030 called CEL good for. Only the preview reads in bulk, bounded in SQL by kind and capped.
  • Control plane: rules use the same database control-plane pattern as queue pause and ADR-038 overrides.
  • Not a workflow engine: a rule decides whether a job runs at all, not what work follows, and keeps no relation between jobs. That passes the test ADR-046 (ADR-046: handler-staged follow-up jobs #556) sets out. Rules aren't offered as a routing API on ClientBuilder or InsertOpts.

The rejected alternatives are a claim-time SQL filter, rejection at enqueue, per-kind pause only, a check in user code, and a new held state. The ADR lists each with its reasons.

Open questions

  • Default action: whether hold should be the default.
  • Matching on errors: whether rules may match on a job's past errors, for example to quarantine jobs that failed with OOM.
  • Faster propagation: whether rule changes need a path faster than the 10-second refresh.

Notes

Operators can hold, dead-letter or cancel claimed jobs of one kind,
optionally only those matching a CEL predicate over their args, without
pausing the queue or deploying. Rules are checked after the claim and
applied through the existing snooze, DLQ and cancel paths, so the claim
query and its storage proofs are untouched. A hold lasts until the rule
expires, so held jobs are not re-claimed every few seconds. Phase 1 ships
rules by kind and queue; phase 2 adds expressions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016oDvumkeByijpFvqb85Qbj
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-27T19:07:19.250145Z bc8ea0f PR opened
ℹ️ 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 review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 45 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: df302129-d907-4ebf-8e84-aef98613fe00
Commits

Reviewing files that changed from the base of the PR and between bbc5173 and 6431c8c.

Files selected for processing: 2

  • docs/adr/047-operator-skip-rules.md
  • docs/adr/README.md
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@github-actions

github-actions Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-11-08 08:21 UTC

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

ℹ️ 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 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 address that feedback".

Comment thread docs/adr/047-operator-skip-rules.md Resolved
Comment thread docs/adr/047-operator-skip-rules.md Resolved
claude and others added 2 commits October 27, 2026 19:15
Evaluation errors are reported through the runtime snapshot each worker
already publishes, so a failing expression never writes the rules table.
Holds are recorded in awa.job_skip_holds in the snooze's own transaction
instead of in job metadata, which may be any JSON value; release joins on
that table and maintenance clears rows whose job is no longer scheduled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016oDvumkeByijpFvqb85Qbj
@hardbyte
hardbyte merged commit 6a840cc into main Nov 8, 2026
23 checks passed
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