Fix agent source registration and retire legacy Gemini assessment pipeline - #129
Merged
Conversation
…eline The commitment evaluation agent could not register any new evidence: canada.ca rejected the pages endpoint's User-Agent (20s hang then 500), parl.ca was not on the allowlist despite the prompts telling the agent to use it, and the defuddle CLI truncated piped output at 64KB so large pages failed to parse. - Fetch government pages through PageFetcher with a browser-compatible crawler User-Agent; also used by the RSS entry scraper, which hit the same block - Allow *.parl.ca in the pages endpoint; return 502 with a readable message on timeouts, connection errors and parse failures instead of 500 - Replace the local defuddle CLI with the hosted worker (deffudler.svc.canadasbuilding.com), configured via DEFUDDLE_API_KEY and optional DEFUDDLE_API_URL; Rails still fetches the page and posts the HTML - Default both agent jobs to claude-sonnet-5 (were sonnet-4-6 and opus-4-6) - Agent-created commitment matches start as assessed - Remove the 6-hourly CommitmentAssessmentCronJob and the Gemini CriterionAssessor / CommitmentStatusDeriver pipeline, which wrote criteria alongside the agent; drop the rake tasks that drove it - Chat tolerates orphaned STI types so historical rows from the removed classes still load in the admin
…ion pin - Remove an extra blank line RuboCop flagged in the agent matches controller - Update the relevance filter test to use the `broken` status; `abandoned` was renamed some time ago and the test has failed since - StatcanDatasetsController#show now finds by name or id and returns 404 when nothing matches, instead of rendering `null` with 200 - Drop `--ensure-latest` from bin/brakeman. It exits 5 whenever a newer Brakeman ships, which is why scan_ruby has failed on main since March - Only render entry URLs as links in the scraping health admin view when they are http(s); add config/brakeman.ignore for that check (Brakeman cannot see the guard) and for the Rails 8.0 end-of-life notice
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The commitment evaluation agent (
AgentEvaluateCommitmentJob) has been unable to register any new evidence since roughly March. Every canada.ca registration timed out and parl.ca pages were rejected outright, so the agent could only cite source URLs that already existed in the database. This PR fixes the fetch path, moves HTML extraction to the hosted defuddle worker, upgrades the agent model, and removes the old Gemini criteria-assessment pipeline that was writing the same fields as the agent.Root causes found
BuildCanada-Tracker/1.0(connection reset over HTTP/2, indefinite hang over HTTP/1.1). The pages endpoint hit its 20s read timeout and returned an unhandled 500. The RSS entry scraper sent http.rb's default agent, which is blocked the same way.Changes
PageFetcher(new) wraps http.rb with a browser-compatible crawler User-Agent that canada.ca accepts. Used byApi::Agent::PagesControllerandEntry#fetch_data!.*.parl.caallowed;HTTP::TimeoutError,HTTP::ConnectionError, SSL and DNS errors and parse failures return 502 with a readable error.Defuddleis now a client for the hosted worker atdeffudler.svc.canadasbuilding.com(POST /api/convertwith the already-fetched HTML). Same[markdown, html]return shape; callers pass the page URL. RequiresDEFUDDLE_API_KEY;DEFUDDLE_API_URLis optional. The worker side (accepthtmlin the request, fix its own User-Agent) is already deployed.claude-sonnet-5in both jobs. They previously disagreed (claude-sonnet-4-6for commitments,claude-opus-4-6for entries). Sonnet 5 is cheaper than Sonnet 4.6.CommitmentAssessmentCronJob(6-hourly),CommitmentAssessmentJob,CriterionAssessor,CommitmentStatusDeriver, andlib/tasks/reevaluate.rake; backfill phase 5 and a stale rake hint dropped. This Gemini pipeline re-wrote criteria statuses and evidence notes that the agent also owns.Chatloads unknown STI types as plainChatso the ~13k historical rows from the removed classes still open in Avo.Deployment notes
DEFUDDLE_API_KEYon both thewebandworkercontainers (passthrough added todocker-compose.prod.yml). Without it, page registration and entry scraping fail fast with a clear error.defuddle-cli, andpackage.jsonlistsdefuddle. Nothing uses them now; left for a follow-up.agent/run_batch.shandagent/.env.examplestill reference the removed Python agent and are dead; also left for a follow-up.Testing
Local, against a copy of the production database and the deployed worker, with no defuddle CLI on PATH:
POST /api/agent/pages/fetchnow returns 200 for a canada.ca news release (was 500 after 20s), the 300KB ESDC departmental plan (was 500 after 20s, then a 64KB truncation error), a LEGISinfo bill page (was 422), and a Canada Gazette index. An unresolvable host returns 502 with a message.AgentEvaluateCommitmentJob.perform_nowon three commitments (2365, 2392, 2394): every API call 2xx. On the submarine commitment the agent found and correctly sourced the July 2026 preferred-supplier announcement; on the drone-fleet commitment it registered five new sources and created four events. Status decisions followed the evidence hierarchy in all three runs.Rails.application.eager_load!succeeds;bin/rails -Tlists the remaining rake tasks; aChatrow typedCriterionAssessorloads asChatwith its messages.Not run locally:
bundle exec rubocopandbin/rails test. This machine has Ruby 4.0.2 and the project pins 3.4.7; RuboCop's parser and Minitest do not load under 4.0.2. Relying on CI for both.