Skip to content

Architecture

C4 Level 2 — Container Diagram

graph TB
    subgraph "ATL-E System"
        APP[ATL-E Console App<br>.NET 10]
        STATE[(state.json<br>NFS PVC)]
    end

    subgraph "External Systems"
        GH[GitHub API<br>Issues, PRs, Labels]
        DC[Discord Webhooks<br>Agent channels]
    end

    subgraph "Config"
        YAML[YAML Files<br>repos, agents, timeouts]
    end

    APP -->|Poll issues & PRs| GH
    APP -->|Update labels| GH
    APP -->|Send notifications| DC
    APP -->|Read/Write| STATE
    APP -->|Load| YAML

Component Overview

graph LR
    subgraph "GitHub Layer"
        PM[PrMonitor]
        IM[IssueMonitor]
        LM[LabelManager]
    end

    subgraph "Logic Layer"
        RE[RuleEngine]
        SM[PrStateMachine]
        AE[AssignmentEngine]
    end

    subgraph "State Layer"
        TR[Tracker]
        SF[(state.json)]
    end

    subgraph "Output Layer"
        DN[DiscordNotifier]
        MF[MessageFormatter]
    end

    PM --> RE
    IM --> RE
    IM --> AE
    RE --> SM
    RE --> TR
    AE --> TR
    RE --> DN
    AE --> LM
    AE --> DN
    DN --> MF
    TR --> SF

Components

GitHub Layer

Component Purpose
PrMonitor Polls open PRs across all repos. Fetches reviews, check runs, comments.
IssueMonitor Polls open issues. Detects claims from comments and assignees.
LabelManager Adds/removes labels on GitHub issues (in-progress, claimed-*).

Logic Layer

Component Purpose
PrStateMachine Computes PR state from check runs, reviews, and comments. 9 states.
RuleEngine Evaluates notification rules against PR/issue state. 8 rules.
AssignmentEngine Matches agent-ready issues to available agents by capability.

State Layer

Component Purpose
Tracker Tracks PR states, notification cooldowns, agent assignments.
state.json Persisted to NFS PVC between CronJob runs.

Output Layer

Component Purpose
DiscordNotifier Sends webhook messages to Discord channels.
MessageFormatter Formats notifications as plain text (agents can't read embeds).

PR State Machine

stateDiagram-v2
    [*] --> AwaitingCi: PR opened
    AwaitingCi --> CiFailed: Check fails
    AwaitingCi --> AwaitingReview: All checks pass
    AwaitingCi --> CopilotUnresolved: Copilot comments
    CiFailed --> AwaitingCi: Author pushes fix
    AwaitingReview --> ChangesRequested: Reviewer requests changes
    AwaitingReview --> Approved: Reviewer approves
    ChangesRequested --> AwaitingFollowup: Author responds
    AwaitingFollowup --> AwaitingReview: Reviewer re-reviews
    Approved --> ReadyToMerge: CI green
    ReadyToMerge --> [*]: Merged
    CopilotUnresolved --> AwaitingReview: Author resolves

Notification Rules

# Rule Trigger Target
1 CI Failed Check run fails PR author
2 Changes Requested Review with changes_requested PR author
3 Awaiting Followup Author responded, reviewer silent >90min Reviewer
4 Ready to Merge Approved + CI green, not merged >60min Admin
5 Blocked No Response Agent says "blocked", no reply >120min Admin
6 Copilot Unresolved Copilot comments unresolved >60min PR author
7 Issue Claimed No PR Issue claimed >4h, no PR Claiming agent
8 Awaiting Review PR awaiting review >120min Review-E