# ebrahimabdelwahed/study-agent-harness architecture

> Architecture diagram of the GitHub repository ebrahimabdelwahed/study-agent-harness, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-25). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/ebrahimabdelwahed/study-agent-harness
- Repository: https://github.com/ebrahimabdelwahed/study-agent-harness

## Overview

Study Agent Harness is a provider-neutral Python library and reference CLI for building source-grounded study agents. Its main workflow is to create a local course, ingest source material, rebuild retrieval, then answer a question using retrieved evidence and an explicitly configured model; verified answers can be committed to a session. Canonical state is an append-only event stream, with projections and local indexes serving reads and recovery. The README documents additional assessment, artifact, lifecycle, and export capabilities. Sampled source supports several service boundaries; some CLI-to-service wiring is inferred only from the documented product workflow.

Main entry points: [`src/study_agent/application/harness.py`](https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/application/harness.py) (Repository harness), [`src/study_agent/ports/storage.py`](https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/ports/storage.py) (Domain event stream), [`src/study_agent/application/grounding_ask.py`](https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/application/grounding_ask.py) (Grounded answers), [`src/study_agent/ingestion/service.py`](https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/ingestion/service.py) (Source ingestion)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_interface["User Interface"]
  node_cli["Reference CLI<br/>[main.py]"]
  node_harness["Repository harness<br/>[harness.py]"]
  node_lifecycle["Desired-state lifecycle<br/>[service.py]"]
  node_export["Portable export<br/>[export.py]"]
end

subgraph group_learning["Study Workflow"]
  node_ingestion["Source ingestion<br/>[service.py]"]
  node_knowledge["Knowledge shaping"]
  node_retrieval["Evidence retrieval"]
  node_grounding["Grounded answers<br/>[grounding_ask.py]"]
  node_sessions["Study sessions<br/>[service.py]"]
end

subgraph group_canonical["Canonical State"]
  node_courses["Course records<br/>[service.py]"]
  node_artifacts["Study artifacts<br/>[service.py]"]
  node_assessments["Assessments<br/>[service.py]"]
  node_events[("Domain event stream<br/>[storage.py]")]
  node_projections["Read projections<br/>[projection.py]"]
end

subgraph group_runtime["Agent Runtime"]
  node_playbooks["Playbook engine<br/>[engine.py]"]
  node_capabilities["Capability dispatch<br/>[gateway.py]"]
  node_workers["Isolated workers<br/>[service.py]"]
end

subgraph group_adapters["Local Adapters"]
  node_sqlite[("SQLite stores")]
  node_filesystem["Filesystem adapters"]
  node_model["Model adapter"]
end

node_user(("Operator / host"))
node_host(("Agent host"))

node_user -->|"issues commands"| node_cli
node_cli -->|"dispatches requests"| node_harness
node_harness -->|"ingests sources"| node_ingestion
node_ingestion -->|"commits revisions"| node_events
node_ingestion -->|"rebuilds index"| node_retrieval
node_retrieval -->|"searches knowledge"| node_knowledge
node_harness -->|"handles ask"| node_grounding
node_grounding -->|"retrieves evidence"| node_retrieval
node_grounding -->|"requests generation"| node_model
node_grounding -->|"commits verified answer"| node_sessions
node_sessions -->|"appends events"| node_events
node_courses -->|"appends events"| node_events
node_artifacts -->|"appends events"| node_events
node_assessments -->|"appends events"| node_events
node_events -->|"replayed into"| node_projections
node_harness -->|"runs study behavior"| node_playbooks
node_playbooks -->|"dispatches capabilities"| node_capabilities
node_workers -->|"executes isolated runs"| node_capabilities
node_lifecycle -->|"plans canonical changes"| node_courses
node_harness -->|"exports course state"| node_export
node_sqlite -->|"implements event store"| node_events
node_filesystem -->|"provides local repository"| node_harness
node_host -.->|"binds trusted context"| node_harness

click node_cli "https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/cli/main.py"
click node_harness "https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/application/harness.py"
click node_ingestion "https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/ingestion/service.py"
click node_knowledge "https://github.com/ebrahimabdelwahed/study-agent-harness/tree/main/src/study_agent/knowledge"
click node_retrieval "https://github.com/ebrahimabdelwahed/study-agent-harness/tree/main/src/study_agent/retrieval"
click node_grounding "https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/application/grounding_ask.py"
click node_sessions "https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/sessions/service.py"
click node_courses "https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/courses/service.py"
click node_artifacts "https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/artifacts/service.py"
click node_assessments "https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/assessments/service.py"
click node_events "https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/ports/storage.py"
click node_projections "https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/ingestion/projection.py"
click node_playbooks "https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/playbooks/engine.py"
click node_capabilities "https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/capabilities/gateway.py"
click node_workers "https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/workers/service.py"
click node_lifecycle "https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/lifecycle/service.py"
click node_export "https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/application/export.py"
click node_sqlite "https://github.com/ebrahimabdelwahed/study-agent-harness/tree/main/src/study_agent/adapters/sqlite"
click node_filesystem "https://github.com/ebrahimabdelwahed/study-agent-harness/tree/main/src/study_agent/adapters/filesystem"
click node_model "https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/adapters/model/openai_compatible.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_cli,node_harness,node_lifecycle,node_export toneBlue
class node_ingestion,node_knowledge,node_retrieval,node_grounding,node_sessions toneAmber
class node_courses,node_artifacts,node_assessments,node_events,node_projections toneMint
class node_playbooks,node_capabilities,node_workers toneRose
class node_sqlite,node_filesystem,node_model,node_user,node_host toneIndigo
```

## Components

### User Interface

- [Reference CLI](https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/cli/main.py): `src/study_agent/cli/main.py`
- [Repository harness](https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/application/harness.py): `src/study_agent/application/harness.py`
- [Desired-state lifecycle](https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/lifecycle/service.py): `src/study_agent/lifecycle/service.py`
- [Portable export](https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/application/export.py): `src/study_agent/application/export.py`

### Study Workflow

- [Source ingestion](https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/ingestion/service.py): `src/study_agent/ingestion/service.py`
- [Knowledge shaping](https://github.com/ebrahimabdelwahed/study-agent-harness/tree/main/src/study_agent/knowledge): `src/study_agent/knowledge`
- [Evidence retrieval](https://github.com/ebrahimabdelwahed/study-agent-harness/tree/main/src/study_agent/retrieval): `src/study_agent/retrieval`
- [Grounded answers](https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/application/grounding_ask.py): `src/study_agent/application/grounding_ask.py`
- [Study sessions](https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/sessions/service.py): `src/study_agent/sessions/service.py`

### Canonical State

- [Course records](https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/courses/service.py): `src/study_agent/courses/service.py`
- [Study artifacts](https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/artifacts/service.py): `src/study_agent/artifacts/service.py`
- [Assessments](https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/assessments/service.py): `src/study_agent/assessments/service.py`
- [Domain event stream](https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/ports/storage.py): `src/study_agent/ports/storage.py`
- [Read projections](https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/ingestion/projection.py): `src/study_agent/ingestion/projection.py`

### Agent Runtime

- [Playbook engine](https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/playbooks/engine.py): `src/study_agent/playbooks/engine.py`
- [Capability dispatch](https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/capabilities/gateway.py): `src/study_agent/capabilities/gateway.py`
- [Isolated workers](https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/workers/service.py): `src/study_agent/workers/service.py`

### Local Adapters

- [SQLite stores](https://github.com/ebrahimabdelwahed/study-agent-harness/tree/main/src/study_agent/adapters/sqlite): `src/study_agent/adapters/sqlite`
- [Filesystem adapters](https://github.com/ebrahimabdelwahed/study-agent-harness/tree/main/src/study_agent/adapters/filesystem): `src/study_agent/adapters/filesystem`
- [Model adapter](https://github.com/ebrahimabdelwahed/study-agent-harness/blob/main/src/study_agent/adapters/model/openai_compatible.py): `src/study_agent/adapters/model/openai_compatible.py`

### Other components

- **Operator / host**
- **Agent host**

## Connections

- Operator / host → Reference CLI: issues commands
- Reference CLI → Repository harness: dispatches requests
- Repository harness → Source ingestion: ingests sources
- Source ingestion → Domain event stream: commits revisions
- Source ingestion → Evidence retrieval: rebuilds index
- Evidence retrieval → Knowledge shaping: searches knowledge
- Repository harness → Grounded answers: handles ask
- Grounded answers → Evidence retrieval: retrieves evidence
- Grounded answers → Model adapter: requests generation
- Grounded answers → Study sessions: commits verified answer
- Study sessions → Domain event stream: appends events
- Course records → Domain event stream: appends events
- Study artifacts → Domain event stream: appends events
- Assessments → Domain event stream: appends events
- Domain event stream → Read projections: replayed into
- Repository harness → Playbook engine: runs study behavior
- Playbook engine → Capability dispatch: dispatches capabilities
- Isolated workers → Capability dispatch: executes isolated runs
- Desired-state lifecycle → Course records: plans canonical changes
- Repository harness → Portable export: exports course state
- SQLite stores → Domain event stream: implements event store
- Filesystem adapters → Repository harness: provides local repository
- Agent host → Repository harness: binds trusted context
