Gitlab Poller

Last updated: April 25, 2026

GitLab Poller Integration

File: assistant/gitlab_poller.go (114 lines), assistant/heartbeat.go (Loop 15)

The GitLab integration uses a polling architecture rather than webhooks to detect code changes and trigger the Gilfoyle agent for security analysis.

Architecture Overview

flowchart LR
    A[heartbeat.go<br/>Loop 15] -->|5 min interval| B[PollGitLabForChanges]
    B -->|GET /api/v4/events| C[GitLab API<br/>gitlab.dlan]
    C -->|JSON events| D{New Event?}
    D -->|Yes| E[Queue for Batch Analysis]
    D -->|No| F[Continue polling]
    E -->|accumulate 24h window| G[Nightly Ritual]
    G -->|TaskType: gitlab_push_notice| H[Gilfoyle Session]

GitLab Push Batching (commit 2d21c25c)

The poller now implements 24-hour batch analysis to avoid triggering Gilfoyle for every individual push. This reduces noise and allows Gilfoyle to perform a consolidated security audit.

Key Components

Function Purpose
PollGitLabForChanges() Queries GitLab API for new push events
loadGitLabState() Loads last event ID and pending summaries from state file
saveGitLabState() Persists state to logs/gitlab_poller_state.json
WasThereActivityInLast24Hours() Checks for recent activity (used by nightly ritual)

State Tracking

{
  "last_event_id": 12345,
  "last_change_time": "2026-04-12T10:30:00Z",
  "last_analysis_time": "2026-04-12T03:00:00Z",
  "pending_summaries": ["push summary 1", "push summary 2"]
}
Field Purpose
LastEventID Compared against new events to detect changes
LastChangeTime Timestamp of most recent push (for 24h activity check)
LastAnalysisTime When the last batch analysis was performed (cooldown tracking)
PendingSummaries Queued push notifications waiting for batch analysis

3. Heartbeat Loop 15 (heartbeat.go:461-525)

Feature Interval Purpose
Push Detection 5 minutes (day) Polls for new commits
Adaptive Polling 1 hour (night 20:00-08:00) Reduces API load during quiet hours
Nightly Security Ritual 03:00 daily If activity in last 24h, Gilfoyle + SkriptKiddie audit

Trigger Flow

On Push Detection

  1. PollGitLabForChanges() queries /api/v4/events?action=pushed&per_page=1
  2. If eventID > state.LastEventID:
    • Updates state file
    • Constructs summary: "New push detected in Project ID X by user: "message"
    • Triggers Gilfoyle with TaskType: "gitlab_push_notice"

Nightly Security Ritual (03:00)

  1. Checks WasThereActivityInLast24Hours()
  2. If true, triggers Gilfoyle with prompt:
    SYSTEM TASK: Nightly Security Ritual.
    Code changes were detected in the last 24 hours. Coordinate with SkriptKiddie 
    to perform a joint security audit. Identify new dependencies or modified logic 
    and check for known vulnerabilities (CVEs) or exploit PoCs.
    

Configuration

Constant Value Location
GitLabAPIURL http://gitlab.dlan/api/v4 gitlab_poller.go:13
GitLabToken API token for authentication gitlab_poller.go:14
GitLabStateFile assistant/logs/gitlab_poller_state.json gitlab_poller.go:15

Gilfoyle Agent Tools

The Gilfoyle agent has access to a dedicated GitLab monitoring tool:

File Purpose
prompts/tools/gilfoyle/gitlab_monitor.sh Bash wrapper for GitLab API queries
prompts/tools/gilfoyle/gitlab_monitor.md Tool definition and parameters

Available Operations

  • list_projects — Projects user has access to
  • get_project — Project details by ID
  • list_commits — Recent commits for a project
  • get_commit — Commit details with diff
  • list_pipelines — CI/CD pipeline status
  • health_check — GitLab instance health

Troubleshooting

GitLab Not Triggering

Symptom: No Gilfoyle sessions for push events.

Checks:

  1. State file exists? Look for assistant/logs/gitlab_poller_state.json
    • If missing, first push will create it
  2. GitLab reachable? Test: curl http://gitlab.dlan/api/v4/version
  3. API token valid? Check GitLabToken constant
  4. Heartbeat running? Check logs for [GITLAB_MONITOR] prefix

No State File

If gitlab_poller_state.json is missing:

  • First poll will initialize with current event ID
  • No push detected until a NEW event occurs after initialization
  • This is expected behavior on fresh deployments

Why Polling Instead of Webhooks?

Aspect Polling Webhooks
Complexity Simple HTTP GET Requires endpoint + signature validation
Reliability Self-healing on restart Can miss events if endpoint down
Firewall Outbound only Requires inbound port exposure
State Persistent via file Stateless (push-based)

The polling approach was chosen for simplicity and reliability in a home-lab environment where GitLab is on an internal network.


See also: Heartbeat & Triggers, Nightly Security Audit