Modules & Agents

Parachute uses a modular architecture where features are loaded as modules from the vault, and custom agents provide specialized AI behaviors. Modules are hash-verified for security; agents are discovered from YAML/Markdown files.

Module System

Modules are the primary extension mechanism. Each module lives in vault/.modules/ and provides features through a registry interface system.

Architecture

┌─────────────────────────────────────────────────────────────┐
│                      Module System                           │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  modules/ (bundled, version-controlled)                      │
│      │                                                       │
│      └──► Bootstrap → vault/.modules/ (on first startup)     │
│                                                              │
│  ModuleLoader (core/module_loader.py)                        │
│      │                                                       │
│      ├──► Discover modules in vault/.modules/                │
│      │                                                       │
│      ├──► Hash verification (SHA-256)                        │
│      │       │                                               │
│      │       ├── New module → auto-approve + record hash     │
│      │       ├── Hash match → load module                    │
│      │       └── Hash mismatch → block pending approval      │
│      │                                                       │
│      ├──► Load module.py via importlib                       │
│      │                                                       │
│      └──► Publish interfaces to registry                     │
│                                                              │
│  Registry (core/interfaces.py)                               │
│      │                                                       │
│      └──► Interface discovery for cross-module dependencies  │
│                                                              │
└─────────────────────────────────────────────────────────────┘

Bundled Modules

Module Version Description Provides Requires
brain 0.1.0 Knowledge graph entity management BrainInterface
chat 0.1.0 Streaming chat with Claude Agent SDK BrainInterface
daily 0.1.0 Daily journal entries and agent framework BrainInterface (optional)

Module Structure

vault/.modules/
├── brain/
│   ├── manifest.yaml      # Module metadata
│   └── module.py          # Module class with setup() + get_router()
├── chat/
│   ├── manifest.yaml
│   └── module.py
└── daily/
    ├── manifest.yaml
    └── module.py

manifest.yaml Format

# Example: modules/brain/manifest.yaml
name: brain
version: "0.1.0"
description: "Knowledge graph entity management"
trust_level: full
provides:
  - BrainInterface

# Example: modules/chat/manifest.yaml
name: chat
version: "0.1.0"
description: "Streaming chat with Claude Agent SDK"
trust_level: full
requires:
  - BrainInterface

# Example: modules/daily/manifest.yaml
name: daily
version: "0.1.0"
description: "Daily journal entries and agent framework"
trust_level: full
optional_requires:
  - BrainInterface

Manifest Fields

Field Type Required Description
name string Yes Module identifier (must match directory name)
version string Yes Semantic version
description string Yes Human-readable description
trust_level string No Required trust: full, vault, sandboxed
provides list No Interface names published to registry
requires list No Required interfaces (fails if missing)
optional_requires list No Optional interfaces (graceful without)

Hash Verification

Security: All Python files and manifest.yaml in a module directory are SHA-256 hashed. New modules are auto-approved on first load. Modified modules are blocked until explicitly approved via CLI.
# Module approval workflow
parachute module list       # See all modules: new/approved/modified
parachute module approve brain   # Record hash, allow loading
parachute module status     # Live server module status (online)
parachute module test       # Test module endpoints (online)

# Hash storage: vault/.parachute/module_hashes.json
{
  "brain": "a1b2c3d4e5f6...",
  "chat": "f6e5d4c3b2a1...",
  "daily": "1a2b3c4d5e6f..."
}

Custom Agents

Custom agents are user-defined AI personas discovered from the vault. They're used for Task tool delegation during chat sessions.

Agent Type Purpose Location
Custom Agents User-defined agents for Task tool delegation .parachute/agents/
Daily Agents Scheduled agents processing journal entries Daily/.agents/*.md

Agent Definition Format

Custom agents are discovered from three file formats:

YAML Format

# .parachute/agents/reviewer.yaml
description: Reviews code for quality and best practices
prompt: |
  You are a code reviewer. Focus on:
  - Code quality
  - Security issues
  - Performance
tools:
  - Read
  - Grep
  - Glob
model: sonnet  # optional: sonnet, opus, haiku

Markdown Format (with frontmatter)

# .parachute/agents/reviewer.md
---
description: Reviews code
tools: [Read, Grep]
model: sonnet
---

# Agent Prompt

You are a code reviewer...

AgentConfig Fields

Field Type Required Description
name string Yes Agent identifier (derived from filename)
description string Yes Brief description shown in Task tool
prompt string Yes System prompt for the agent
tools list No Allowed tools (Read, Grep, Glob, etc.)
model string No Model override (sonnet, opus, haiku)

Daily Agents

Daily agents are scheduled to run automatically and process journal entries.

Daily Agent Configuration

# Daily/.agents/content-scout.md
---
displayName: Content Scout
description: Extracts valuable insights from daily work
schedule:
  enabled: true
  time: "3:00"  # 3:00 AM UTC
output:
  path: "Daily/content-scout/{date}.md"
tools:
  - read_journal
  - read_chat_log
  - read_recent_journals
---

You are a content scout that discovers valuable insights...

DailyAgentConfig Fields

Field Type Default
displayName string Derived from filename
description string Required
schedule.enabled boolean true
schedule.time string "3:00" (UTC)
output.path string Daily/{name}/{date}.md
tools list All daily tools

Daily Agent Tools

Tool Purpose
read_journal(date) Read Daily/journals/{date}.md
read_chat_log(date) Read Daily/chat-log/{date}.md (truncated 10K)
read_recent_journals(days) Read last N days of journals (max 30)
read_recent_sessions(days) Read last N days of chat logs (max 30)
write_output(date, content) Write to configured output path

Scheduler Integration

Daily agents are scheduled using APScheduler with cron triggers.

Scheduler Lifecycle

init_scheduler(vault_path)
        │
        ├── Create AsyncIOScheduler
        │
        ├── Discover agents from Daily/.agents/*.md
        │
        ├── For each agent with schedule.enabled:
        │       │
        │       └── Add CronTrigger job
        │
        └── Start scheduler

Status Monitoring

GET /api/scheduler/status → {
  "running": true,
  "jobs": [
    {
      "id": "daily_content-scout",
      "name": "Content Scout",
      "next_run": "2026-01-29T03:00:00",
      "trigger": "cron[hour='3', minute='0']"
    }
  ],
  "agents": {
    "content-scout": {
      "enabled": true,
      "hour": 3,
      "minute": 0,
      "display_name": "Content Scout"
    }
  }
}

State Persistence

Agent state is persisted for session continuity across runs.

Daily Agent State

# Daily/.{agent_name}/state.json
{
  "agent": "content-scout",
  "backend": "claude-sdk",
  "sdk_session_id": "uuid-here",  # Resume point
  "model": null,
  "last_run_at": "2026-01-28T08:15:30.123456+00:00",
  "last_processed_date": "2026-01-27",
  "run_count": 42,
  "created_at": "2026-01-01T12:00:00+00:00"
}

User Context System

Agents can be personalized with user context loaded from the vault.

Context Loading

load_user_context(vault_path) → (user_name, context_text)
        │
        ├── Read context/curator.md
        │
        ├── Resolve @ references:
        │       @parachute/profile.md
        │       @parachute/projects.md
        │
        └── Extract **Name**: field for personalization

@ Reference Resolution

  • Supports recursive file references
  • Max recursion: 3 levels to prevent loops
  • Injected into agent prompts via {user_name}, {user_context}

Tool Availability by Agent Type

Agent Type Tools MCP Servers Resumable
Custom Agent As defined in config None (SDK inline) No
Daily Agent read_*, write_output daily_{name} + vault MCPs Yes

Key Files

File Purpose
core/module_loader.py Module discovery, hash verification, bootstrap, loading
core/interfaces.py Interface registry for cross-module dependencies
core/agents.py Custom agent discovery and definition parsing
core/agent_loader.py Extended agent parsing with permissions/constraints
core/daily_agent.py Generic daily agent framework
core/daily_agent_tools.py MCP tools for daily agents
core/scheduler.py APScheduler integration with cron triggers
api/modules.py Module management API endpoints
api/scheduler.py Scheduler status and trigger API

Architecture Summary

┌─────────────────────────────────────────────────────────────┐
│                  Modules & Agents                           │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  Module System (vault/.modules/)                             │
│      │                                                       │
│      ├──► brain → Knowledge graph, entity search             │
│      ├──► chat  → Streaming chat via Claude SDK              │
│      └──► daily → Journal entries, daily agent framework     │
│                                                              │
│  Custom Agents (.parachute/agents/)                          │
│      │                                                       │
│      └──► Task Tool Delegation in chat sessions              │
│                                                              │
│  Daily Agents (Daily/.agents/)                               │
│      │                                                       │
│      ├──► APScheduler (cron)                                 │
│      │                                                       │
│      └──► Journal Processing → Output                        │
│                                                              │
│  Hash Verification                                           │
│      │                                                       │
│      └──► SHA-256 of Python files + manifest                 │
│           New → auto-approve, Modified → block until CLI     │
│                                                              │
└─────────────────────────────────────────────────────────────┘