Agents & Skills
AEGIS no longer ships a fixed roster of purpose-built agents. Domain capability is delivered by skills reached through skill routers, and domain logic lives in installable packs. Skills, routers, rules, prompts, and settings are tenant-configurable data served by the Agent Config Service (port 8010) — not code and not YAML checked into the repo.
Historical note: four purpose-built agents (Rule 37, Rule 32, Compliance Monitor, Flaring
Monitor) were defined as agents/*.yaml and shown in the conversation picker. They were
retired on 2026-07-07. Those YAML files still exist for historical context but are not
read at runtime. This page describes the current model.
The two seeded agents
New conversations choose between two seeded agents (rows in the agent_definitions table, no YAML file):
| Agent | agent_key | Role |
|---|---|---|
| General | general | Skill-less mode. Starts with only core tools and recruits domain skills at runtime via routers. This is how a user reaches Rule 37 / Rule 32 / watch capabilities. |
| Creator | creator | The Skill Creator (R38). Walks a user through authoring a new skill — drafts, code blocks, rules, dry runs, submit-for-review. It never approves or publishes; admin approval is what makes an authored skill loadable. Seeded by seed_creator(). |
The Conversations page offers only general and creator. There is no per-domain agent to pick — General recruits whatever skill the conversation needs.
How routing works
A general-mode conversation does not carry domain skills up front. Instead:
- Router manifest — the system prompt includes a manifest of active skill routers (the
skill_routerstable). Each router is an admin-curated recruitment taxonomy entry with arouter_keyand arecruitment_blurb. pull_routers— the LLM calls this ordinary tool to read the full author descriptions of the skills a router routes to (its approvedskill_router_maprows).select_skill— the LLM then loads one skill byskill_key, which injects its Tier 2 specification into the conversation.
Routers are soft-deactivated only (never hard-deleted) so the manifest-delta watermark cannot miss a change. Seeded routers and the skills they route to:
| Router | Routes to | Covers |
|---|---|---|
spacing | rrc_rule37 | Well spacing, Rule 37 exceptions, offset distances, lease-line and between-well requirements |
flaring | rrc_rule32, flaring_watch | Flaring/venting exception filing (rrc_rule32) and read-only flaring surveillance (flaring_watch) |
compliance | compliance_watch, filings_watch | Portfolio compliance posture and filing-queue status |
field_events | events_watch | The event feed |
The flaring router carries a watch/file pair: monitoring and status questions route to flaring_watch; preparing an exception application routes to rrc_rule32. The read-only flaring_watch skill also exposes flaring_volume_status and emissions_screening blocks, which reuse the rrc_rule32 code-block implementations under distinct tool names.
The four retired agents map onto today’s model as: Rule 37 → the rrc_rule37 skill via the
spacing router; Rule 32 → the rrc_rule32 skill via the flaring router; the Compliance
Monitor’s conversational role → the compliance_watch / filings_watch / events_watch skills
plus the compliance dashboard; the Flaring Monitor’s role → the read-only flaring_watch skill
plus the flaring dashboard. The orchestration engine’s last agent_type-keyed tool branch (the
R35-FENCE) was removed; a monitor-typed /execute request degrades to core tools only. The
agent_type enum values remain valid for historical snapshots and replay.
HITL travels with the skill
Human-in-the-loop checkpoints are not tied to agent identity. They fire from seeded skill require_hitl rules (an after_tool_call trigger attached to the skill) and from the before_tool_call mutating-tool gate. Because the rule travels with the skill, filing assembly stays gated no matter which agent recruited the skill. Seeded RRC rules:
| Skill | Checkpoint | Trigger |
|---|---|---|
rrc_rule37 | pre_filing | Filing assembly (before RRC submission) |
rrc_rule37 | good_cause_review | Good-cause narrative |
rrc_rule32 | pre_filing | R-32 filing assembly |
For rrc_rule32, emissions is a model-supplied calculation, not a filing gate — so there is no emissions HITL rule. The approval_node is fail-closed: it pauses (awaiting_hitl) when a mandatory checkpoint cannot be recorded; only HITL_BREAK_GLASS restores fail-open for a logged emergency.
Skill injection tiers
Skills use a three-tier injection architecture, tracked by the injection ledger (a Redis Hash at skill:ledger:{conversation_id}) to prevent duplicate injection:
- Tier 1 — compact manifest (name, description, trigger keywords). Always available so the LLM knows what routers/skills exist.
- Tier 2 — full skill specification (steps, requirements, output format). Injected on-demand when the LLM calls
select_skill. - Tier 3 — rare artifact content (reference tables, form-field guides, regulatory text). Injected only when the specific skill requires it.
Packs — where domain logic lives
Each compliance domain is an installable pack at services/orchestration-engine/src/orchestration/packs/<name>/manifest.yaml (out-of-tree via PACKS_DIR), discovered at startup. A manifest declares the pack’s skills (descriptors), checklist template, and assessment recipe (a five-verb DSL plus pack-declared Cypher; thresholds resolve from rule_versions). Adding or removing a pack directory needs zero core edits.
RRC ships five packs — the first installed vertical:
| Pack | Domain | Page |
|---|---|---|
rule_37 | Rule 37 spacing exceptions | Rule 37 Pack |
rule_32 | Rule 32 flaring/venting exceptions | Rule 32 Pack |
form_pr | Form PR monthly production reports | — |
flaring_monitor | Continuous flaring compliance | Flaring Pack |
epa_oooob | EPA OOOOb methane compliance (fifth pack, born after horizontalization) | — |
The deterministic config-driven assessors (R41_CONFIG_ASSESSORS, ON by default since 2026-07-12) run from these recipes; the legacy imperative RRC assessors in compliance/engine.py remain only as a parity oracle / fallback.
Core tools vs. skill-scoped tools
Every conversation starts with a small set of core tools regardless of agent: entity_resolve (resolve a name to an entity), context_assemble (fetch a resolved entity’s details), and render_chart (present an AEGIS chart, R43). Oil-and-gas tools — spacing_calculation, offset_well_analysis, rule37_filing_assembly, good_cause_narrative, the Rule 32 filing/emissions blocks, and so on — are skill-scoped code blocks: they become available only once the relevant skill is loaded via select_skill.
Budgets and models
Token and cost budgets are two-tier (per-conversation cumulative and per-turn) and enforced by orchestration/budget.py; see the Budget glossary entry. The effective LLM model is tenant-configured via the Platform Settings admin page (resolution: request override → tenant setting → env floor); the box default is anthropic/claude-sonnet-5. There are no per-agent model or budget YAML files anymore.
Source Files
| File | Purpose |
|---|---|
services/agent-config-service/src/agent_config/routers_seed.py | Seeded routers + router→skill mappings |
services/agent-config-service/src/agent_config/seed_rrc_skills.py | Seeded rrc_rule37 / rrc_rule32 skills |
services/agent-config-service/src/agent_config/seed_watch_skills.py | Seeded watch skills (flaring_watch, compliance_watch, …) |
services/agent-config-service/src/agent_config/seed_rrc_skill_rules.py | Seeded require_hitl rules |
services/agent-config-service/src/agent_config/seed_creator.py | Seeds the creator agent |
services/orchestration-engine/src/orchestration/packs/*/manifest.yaml | Pack manifests (skills, checklist, assessment) |
services/orchestration-engine/src/orchestration/selection_tools.py | pull_routers / select_skill |
services/orchestration-engine/src/orchestration/tools.py | Core + skill-scoped tool definitions |
services/orchestration-engine/src/orchestration/budget.py | Two-tier budget enforcement |
services/orchestration-engine/src/orchestration/nodes.py | approval_node (fail-closed HITL) |