From 94dd1f6616417af1268e20dde255830e4aa7520d Mon Sep 17 00:00:00 2001 From: xrendan Date: Thu, 10 Sep 2026 13:47:28 -0600 Subject: [PATCH 1/2] Drop enqueue limit and skip same-day re-evaluation unless forced - Remove enqueue_limit: 550 from AgentEvaluateCommitmentJob; the weekly scan enqueues ~600 commitments and GoodJob silently dropped the excess - Skip commitments whose last_assessed_at is today unless force: true, so a re-run of the scan or a duplicate manual enqueue doesn't repeat a ~2 minute agent session --- app/jobs/agent_evaluate_commitment_job.rb | 17 +++++++++-- .../agent_evaluate_commitment_job_test.rb | 30 +++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/app/jobs/agent_evaluate_commitment_job.rb b/app/jobs/agent_evaluate_commitment_job.rb index b1783b6..f21db10 100644 --- a/app/jobs/agent_evaluate_commitment_job.rb +++ b/app/jobs/agent_evaluate_commitment_job.rb @@ -6,14 +6,21 @@ class AgentEvaluateCommitmentJob < ApplicationJob good_job_control_concurrency_with( perform_limit: 5, - enqueue_limit: 550, key: "AgentEvaluateCommitmentJob" ) retry_on GoodJob::ActiveJobExtensions::Concurrency::ConcurrencyExceededError, wait: 60.seconds, attempts: Float::INFINITY retry_on StandardError, wait: 30.seconds, attempts: 3 - def perform(commitment, trigger_type: "manual", as_of_date: nil) + # Each run is a full agent session (~2 minutes). Skip commitments already + # assessed today unless force: true, so a re-run of the weekly scan or a + # duplicate manual enqueue doesn't repeat work. + def perform(commitment, trigger_type: "manual", as_of_date: nil, force: false) + if !force && assessed_today?(commitment) + Rails.logger.info("AgentEvaluateCommitmentJob: Skipping commitment #{commitment.id}, already assessed today at #{commitment.last_assessed_at.iso8601} (pass force: true to re-run)") + return + end + current_date = as_of_date || Date.today.iso8601 prompt = format(AgentPrompts::EVALUATE_COMMITMENT_PROMPT, commitment_id: commitment.id, current_date: current_date) hook_script = agent_dir.join(".claude/hooks/on_stop_commitment.sh").to_s @@ -30,4 +37,10 @@ def perform(commitment, trigger_type: "manual", as_of_date: nil) Rails.logger.info("AgentEvaluateCommitmentJob: Success for commitment #{commitment.id}") end + + private + + def assessed_today?(commitment) + commitment.last_assessed_at.present? && commitment.last_assessed_at.to_date == Date.current + end end diff --git a/test/jobs/agent_evaluate_commitment_job_test.rb b/test/jobs/agent_evaluate_commitment_job_test.rb index e6d625b..727104f 100644 --- a/test/jobs/agent_evaluate_commitment_job_test.rb +++ b/test/jobs/agent_evaluate_commitment_job_test.rb @@ -33,6 +33,36 @@ class AgentEvaluateCommitmentJobTest < ActiveJob::TestCase assert_match(%r{http://127\.0\.0\.1:1 is unreachable}, error.message) end + test "skips a commitment already assessed today" do + ENV["AGENT_API_KEY"] = "test-key" + ENV["RAILS_API_URL"] = "http://127.0.0.1:1" + @commitment.update!(last_assessed_at: 1.hour.ago) + + AgentEvaluateCommitmentJob.perform_now(@commitment) + + assert_no_enqueued_jobs only: AgentEvaluateCommitmentJob + end + + test "re-runs a commitment assessed today when forced" do + ENV["AGENT_API_KEY"] = "test-key" + ENV["RAILS_API_URL"] = "http://127.0.0.1:1" + @commitment.update!(last_assessed_at: 1.hour.ago) + + error = perform_and_capture_retry_error(AgentEvaluateCommitmentJob.new(@commitment, force: true)) + + assert_instance_of RunsClaudeAgent::ApiUnreachableError, error + end + + test "runs a commitment last assessed on a previous day" do + ENV["AGENT_API_KEY"] = "test-key" + ENV["RAILS_API_URL"] = "http://127.0.0.1:1" + @commitment.update!(last_assessed_at: 1.day.ago.end_of_day - 1.hour) + + error = perform_and_capture_retry_error(AgentEvaluateCommitmentJob.new(@commitment)) + + assert_instance_of RunsClaudeAgent::ApiUnreachableError, error + end + private # retry_on rescues the failure and re-enqueues the job; the error is only From 465bf750ba79541b1c2cebda33644b7618779386 Mon Sep 17 00:00:00 2001 From: xrendan Date: Thu, 10 Sep 2026 13:50:25 -0600 Subject: [PATCH 2/2] Remove GoodJob concurrency control from AgentEvaluateCommitmentJob With enqueue_limit gone and perform_limit removed there is nothing left for the extension to enforce; concurrency is bounded by the worker thread count. --- app/jobs/agent_evaluate_commitment_job.rb | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/app/jobs/agent_evaluate_commitment_job.rb b/app/jobs/agent_evaluate_commitment_job.rb index f21db10..a492596 100644 --- a/app/jobs/agent_evaluate_commitment_job.rb +++ b/app/jobs/agent_evaluate_commitment_job.rb @@ -1,15 +1,9 @@ class AgentEvaluateCommitmentJob < ApplicationJob - include GoodJob::ActiveJobExtensions::Concurrency include RunsClaudeAgent queue_as :default - good_job_control_concurrency_with( - perform_limit: 5, - key: "AgentEvaluateCommitmentJob" - ) - - retry_on GoodJob::ActiveJobExtensions::Concurrency::ConcurrencyExceededError, wait: 60.seconds, attempts: Float::INFINITY + # Concurrency is bounded only by the worker's thread count (good_job.max_threads). retry_on StandardError, wait: 30.seconds, attempts: 3 # Each run is a full agent session (~2 minutes). Skip commitments already