feat: governance compliance cron, MCP tools, and govClient - #76
Conversation
…ation Wires ChittyCommand as the orchestrator for governance/compliance monitoring: - Job types: add sos_status, recorder_filings, assessor_check to ScrapeJobType union and all validation arrays (jobs, MCP, sync) - govClient: new integration client for ChittyGov API (compliance calendar, verify filing, list monitors) - Cron Phase 11: syncGovernanceCompliance() — pulls upcoming filings from ChittyGov (60-day window), upserts into cc_obligations as category='governance', enqueues verification scrapes for active monitors - MCP tools: query_compliance_calendar and verify_compliance_filing proxying to ChittyGov - Env: add CHITTYGOV_URL binding - Sync routes: sos_status/recorder_filings/assessor_check as valid manual trigger sources Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
chittycommand-ui | 779b1af | Apr 06 2026, 10:37 PM |
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThis PR introduces a ChittyGov compliance integration by adding environment configuration bindings, a new integration layer with API client and data interfaces, a governance-focused cron phase that syncs compliance deadlines and enqueues verification jobs, new scrape job types, and MCP tools for querying and verifying filings. Changes
Sequence DiagramsequenceDiagram
participant Cron as Cron Scheduler
participant Sync as syncGovernanceCompliance
participant Gov as ChittyGov API
participant DB as Database
participant Queue as Job Queue
Cron->>Sync: trigger with env, sql
Sync->>Gov: getComplianceCalendar(60 days)
Gov-->>Sync: {filings, total}
Sync->>DB: upsert filing → cc_obligations
Sync->>DB: update existing obligation metadata
Sync->>DB: fetch active monitors with scraperId
Sync->>Queue: enqueueJob(scrape payload)
Queue-->>Sync: job enqueued
Sync-->>Cron: return synced count
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
|
|
To use Codex here, create a Codex account and connect to github. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 363a2a5e88
ℹ️ 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".
…ed counter Addresses review findings on PR #76: - Add CHITTYGOV_TOKEN env + Bearer auth header (was missing entirely) - Log HTTP status + response body on non-ok responses (was returning null silently) - Track failed filing count and log summary on partial failures - Fix inverted latePenalty logic (was writing 0 instead of actual penalty) - Add Array.isArray guard on filings response + NaN guard on fee/penalty - Warn explicitly when getMonitors returns null instead of silent skip - Isolate KV read failure with own try-catch and clear label Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Review remediation pushed (e4e3f71)Fixed (7 issues):
Design notes (not blocking, for future):
|
|
To use Codex here, create a Codex account and connect to github. |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (1)
src/lib/job-dispatcher.ts (1)
6-13: Export the scrape job types as a shared runtime constant.This 7-value set is now duplicated in
src/routes/jobs.tsLine 68 andsrc/routes/mcp.tsLines 305, 351, and 1190. ASCRAPE_JOB_TYPEStuple here would keep compile-time and runtime validation from drifting on the next addition.Possible refactor
-export type ScrapeJobType = - | 'court_docket' - | 'cook_county_tax' - | 'mr_cooper' - | 'portal_scrape' - | 'sos_status' - | 'recorder_filings' - | 'assessor_check'; +export const SCRAPE_JOB_TYPES = [ + 'court_docket', + 'cook_county_tax', + 'mr_cooper', + 'portal_scrape', + 'sos_status', + 'recorder_filings', + 'assessor_check', +] as const; + +export type ScrapeJobType = typeof SCRAPE_JOB_TYPES[number];🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/lib/job-dispatcher.ts` around lines 6 - 13, Add and export a runtime tuple constant named SCRAPE_JOB_TYPES containing the seven string literals ('court_docket','cook_county_tax','mr_cooper','portal_scrape','sos_status','recorder_filings','assessor_check') and change the ScrapeJobType type to be derived from it (type ScrapeJobType = typeof SCRAPE_JOB_TYPES[number]); export both so other modules can import SCRAPE_JOB_TYPES instead of duplicating the list and use ScrapeJobType for typing, and update callers in routes to import the constant (and remove their local duplicates).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/index.ts`:
- Around line 56-57: The Env type was extended with CHITTYGOV_URL and
CHITTYGOV_TOKEN but wrangler.toml never provides CHITTYGOV_URL and the token
must be a secret, causing govClient() to return null and MCP routes in
src/routes/mcp.ts to no-op; fix by adding CHITTYGOV_URL to the wrangler.toml
[vars] section (e.g., CHITTYGOV_URL = "https://gov.chitty.cc") and provisioning
CHITTYGOV_TOKEN via the CLI (wrangler secret put CHITTYGOV_TOKEN) so
src/lib/integrations.ts can read the secret at runtime.
In `@src/lib/cron.ts`:
- Around line 913-923: The UPDATE SQL for cc_obligations is missing refresh of
the canonical late_fee column, so modify the UPDATE inside the sql`` block that
sets status/due_date/amount_due/metadata/updated_at to also set late_fee =
${filing.latePenalty} (or CASE WHEN appropriate) so the stored late_fee is
updated when a filing already exists; likewise ensure the INSERT path (the
UPSERT/INSERT block around lines 928-937) includes late_fee =
${filing.latePenalty} in its column list/VALUES so new rows get the same value.
Use the existing symbols (cc_obligations, filing.latePenalty, amount,
jsonb_set/metadata, updated_at) to locate and update both the update and insert
SQL fragments.
- Around line 905-910: Replace the current read-then-insert flow against the
cc_obligations table (the SELECT that looks up metadata->>'filing_id' and the
subsequent INSERT block that runs when no row is found) with a single DB-backed
upsert: create an expression unique index on (category,
(metadata->>'filing_id')) to enforce uniqueness, then perform INSERT ... ON
CONFLICT (...) DO UPDATE to atomically create-or-update the governance
obligation for the given filing.filingId instead of using the existing variable
read path; update the code in src/lib/cron.ts (the code that assigns const
[existing] from cc_obligations and the insert block that follows) to use this
upsert and remove the race-prone SELECT branch.
In `@src/routes/mcp.ts`:
- Around line 373-381: The inputSchema for the 'verify_compliance_filing' route
declares source values as 'scrape', 'email', or 'manual' but elsewhere the
omitted-inputs default is set to 'mcp', producing an undocumented provenance;
update the omitted/default handling to use one of the documented values (e.g.,
'manual') instead of 'mcp'. Locate the route named verify_compliance_filing and
the omittedInputs/default assignment (the other occurrence around the
omittedInputs code block referenced near lines ~1213-1223) and change the
default/source fallback to a documented value ('scrape' | 'email' | 'manual') so
the emitted provenance matches the inputSchema and upstream validation.
---
Nitpick comments:
In `@src/lib/job-dispatcher.ts`:
- Around line 6-13: Add and export a runtime tuple constant named
SCRAPE_JOB_TYPES containing the seven string literals
('court_docket','cook_county_tax','mr_cooper','portal_scrape','sos_status','recorder_filings','assessor_check')
and change the ScrapeJobType type to be derived from it (type ScrapeJobType =
typeof SCRAPE_JOB_TYPES[number]); export both so other modules can import
SCRAPE_JOB_TYPES instead of duplicating the list and use ScrapeJobType for
typing, and update callers in routes to import the constant (and remove their
local duplicates).
🪄 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: 55c8ac14-7ea8-4ae6-8047-cc87563038fa
📒 Files selected for processing (7)
src/index.tssrc/lib/cron.tssrc/lib/integrations.tssrc/lib/job-dispatcher.tssrc/routes/jobs.tssrc/routes/mcp.tssrc/routes/sync.ts
Sets gov.chitty.cc service URL in [vars] alongside other service URLs. Token (CHITTYGOV_TOKEN) will be provisioned via ChittyConnect when ChittyGov adds auth — govClient already handles it conditionally. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
|
To use Codex here, create a Codex account and connect to github. |
🧩 Analysis chain🏁 Script executed: Length of output: 37116 🏁 Script executed: Length of output: 15306
Adversarial Review — PR
|
| Concern | Result |
|---|---|
verifyFiling path traversal via filing_id |
Safe — encodeURIComponent used ✅ |
SQL injection via filing.filingId |
Safe — parameterized Neon queries ✅ |
syncGovernanceCompliance auth bypass |
Safe — /api/sync is under app.use('/api/*', authMiddleware) ✅ |
getMonitors enqueuing inactive monitors |
Safe — called with 'active' filter ✅ |
Unknown monitorType in typeMap |
Safe — if (!jobType) continue guard ✅ |
MCP enqueue_scrape_job job_type validation |
Safe — explicit allowlist ✅ |
Array.isArray guard on filings |
Present ✅ |
isNaN guard on fee/penalty |
Present ✅ |
| Failed filing counter visible in logs | Present ✅ |
Merge gate assessment: The scrapeInput spread order (🔴) is the highest-priority fix before merge — it's a supply-chain confused-deputy issue exploitable via a compromised ChittyGov response. The silent unauthenticated verifyFiling (🔴) is a deployment-config footgun worth one line of warn. The triple-enqueue (🟡) is a real operational bug but not blocking if ChittyGov API rate limits are generous. The remaining items are correctness/hygiene.
🧠 Learnings used
Learnt from: CR
Repo: chittyos/chittycommand PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-03-04T04:42:57.380Z
Learning: Resolve must-fix review comments (security, correctness, compliance, merge blockers) before merge
Learnt from: CR
Repo: chittyos/chittycommand PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-24T18:02:56.403Z
Learning: Applies to src/lib/cron.ts : Sync Notion tasks to cc_tasks table via Phase 9 cron and reconcile legal tasks to cc_disputes via Phase 10 cron
Learnt from: CR
Repo: chittyos/chittycommand PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-09T16:02:20.597Z
Learning: Applies to src/lib/cron.ts : Orchestrate all data source syncs (Plaid, ChittyFinance, court docket, utility scrapers, mortgage, property tax) in `src/lib/cron.ts` as the cron sync orchestrator
✅ Actions performed
Review triggered.
Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.
This reverts commit 9d6c80f.
|
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 45921
Adversarial Re-Review — PR
|
| # | Severity | Issue | Status |
|---|---|---|---|
| 1 | 🔴 HIGH | scrapeInput spread overrides scraper_id/monitor_id |
Open |
| 2 | 🔴 HIGH | Silent unauthenticated verifyFiling when token unset |
Open |
| 3 | 🟡 MEDIUM | Triple-enqueue on concurrent trigger | Open |
| 4 | 🟡 MEDIUM | late_fee not updated on obligation UPDATE |
Open |
| 5 | 🟡 MEDIUM | getMonitors URL raw-concat vs. URLSearchParams |
Open |
| 6 | 🟢 LOW | authority_url unvalidated in metadata |
Open |
Per repo policy, the two 🔴 HIGH items are merge-blocking. Items 3–5 are functional correctness issues that should be resolved before merge given this is financial/compliance data. Item 6 is risk-conditional on downstream rendering.
🧠 Learnings used
Learnt from: CR
Repo: chittyos/chittycommand PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-03-04T04:42:57.380Z
Learning: Resolve must-fix review comments (security, correctness, compliance, merge blockers) before merge
Learnt from: CR
Repo: chittyos/chittycommand PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-24T18:02:56.403Z
Learning: Applies to src/lib/cron.ts : Sync Notion tasks to cc_tasks table via Phase 9 cron and reconcile legal tasks to cc_disputes via Phase 10 cron
Learnt from: CR
Repo: chittyos/chittycommand PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-09T16:02:20.597Z
Learning: Applies to src/lib/cron.ts : Orchestrate all data source syncs (Plaid, ChittyFinance, court docket, utility scrapers, mortgage, property tax) in `src/lib/cron.ts` as the cron sync orchestrator
|
|
To use Codex here, create a Codex account and connect to github. |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 128523
Adversarial Review — PR
|
| # | Severity | Issue | Status |
|---|---|---|---|
| 0 | 🔴 NEW HIGH | CHITTYGOV_URL absent from wrangler.toml after main merge — Phase 11 silently no-ops on deploy |
Open |
| 1 | 🔴 HIGH | scrapeInput spread overrides scraper_id/monitor_id (supply-chain confused-deputy) |
Open |
| 2 | 🔴 HIGH | Silent unauthenticated verifyFiling when CHITTYGOV_TOKEN unset |
Open |
| 3 | 🟡 MEDIUM | Triple-enqueue on concurrent trigger — dedup absence now confirmed in dispatcher code | Open |
| 4 | 🟡 MEDIUM | late_fee not updated on obligation UPDATE |
Open |
| 5 | 🟡 MEDIUM | getMonitors raw URL concat vs. URLSearchParams |
Open |
| 6 | 🟢 LOW | authority_url unvalidated in metadata |
Open |
Three 🔴 HIGH items are merge-blocking per repo policy. Items 3–5 affect financial/compliance data correctness. The new item #0 means the feature is functionally inert post-deploy until resolved.
🧠 Learnings used
Learnt from: CR
Repo: chittyos/chittycommand PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-09T16:02:20.597Z
Learning: Applies to src/lib/cron.ts : Orchestrate all data source syncs (Plaid, ChittyFinance, court docket, utility scrapers, mortgage, property tax) in `src/lib/cron.ts` as the cron sync orchestrator
Learnt from: CR
Repo: chittyos/chittycommand PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-24T18:02:56.403Z
Learning: Applies to src/lib/cron.ts : Sync Notion tasks to cc_tasks table via Phase 9 cron and reconcile legal tasks to cc_disputes via Phase 10 cron
Learnt from: CR
Repo: chittyos/chittycommand PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-03-04T04:42:57.380Z
Learning: Resolve must-fix review comments (security, correctness, compliance, merge blockers) before merge
The remediation in e4e3f71 is solid — all 7 issues look correct. While investigating, I also found two CI failures on this PR that the remediation didn't cover:
I prepared the fix (commit
The branch was deleted after merge so I can't push to it — these changes need a follow-up commit on |
New scrape job types (sos_status, recorder_filings, assessor_check), govClient(), Cron Phase 11, MCP tools (query_compliance_calendar, verify_compliance_filing).
Summary by CodeRabbit
New Features
Chores