# victormerk/planpilot-service architecture

> Architecture diagram of the GitHub repository victormerk/planpilot-service, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-08-02). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/victormerk/planpilot-service
- Repository: https://github.com/victormerk/planpilot-service

## Overview

#### Purpose and entry points
This is a containerized Python HTTP service for IPEXCO that exposes stateful PlanPilot planning sessions over `/api`. The process entry point is `run.py`; request handlers live in `app/rest/sessions.py` and `app/rest/auth.py`. Docker deployment is defined by `Dockerfile`.

#### HTTP boundary and authentication
The REST layer provides health/readiness/capabilities plus session operations. Authorization is enforced for protected routes using a bearer API key, while health and readiness remain unauthenticated. API inputs are converted into service-level session contracts at `app/rest/sessions.py` and `app/service/session_contract.py`; this is the boundary between untrusted HTTP data and planning execution.

#### Session lifecycle and capacity control
A session represents a prepared PDDL task plus a live FASB process whose selected facets persist until explicit stop or TTL expiry. `app/service/session_registry.py` owns active-session tracking, expiration, and admission limits. `app/service/planpilot_service.py` orchestrates session creation, facet queries/selections, and shutdown. This in-process registry is the primary state store and makes session continuity instance-local.

#### Planning pipeline
Session preparation accepts PDDL domain/problem material, parses or hashes it, and invokes Fast Downward to produce the planning representation required by PlanPilot. `app/service/fastdownward_service.py` encapsulates the subprocess boundary and timeout handling; `app/utils/parsing.py` and `app/utils/hashing.py` support validation/identity. The vendored Fast Downward driver performs translation and search: `lib/downward/fast-downward.py`, `lib/downward/src/translate/translate.py`, and `lib/downward/src/search/planner.cc`.

#### PlanPilot/FASB execution
The PlanPilot adapter starts and communicates with the bundled Linux x86_64 FASB executable, maintaining an interactive solver process per session. Core upstream assets are `lib/planpilot/planpilot.py`, `lib/planpilot/bin/fasb`, and `lib/planpilot/scripts/facet-reason.fasb`. PlanPilot includes ASP encodings for sequential horizons and facets in `lib/planpilot/encodings/`. This is a process and platform boundary: production images must be Linux amd64 or emulate it.

#### Persistence model
Persistence is isolated behind `app/persistence/db.py` and `app/persistence/models.py`. Its role is distinct from the active registry: durable records, if used, should not be assumed to contain live solver state. Session-facing orchestration should preserve this separation so database failures or restarts do not leave orphaned subprocesses.

#### Runtime and operational limits
The service runs in Docker and depends on Python plus vendored Python, C++, and native solver components. Configuration is environment-driven for API access, horizon, active-session cap, session TTL, and Fast Downward/FASB/query timeouts. CI builds through `.github/workflows/build.yml`. External network services are not indicated; the material external dependencies are local subprocesses and bundled planner binaries.

Main entry points: [`app/service/planpilot_service.py`](https://github.com/victormerk/planpilot-service/blob/master/app/service/planpilot_service.py) (PlanPilot orchestration), [`lib/planpilot/planpilot.py`](https://github.com/victormerk/planpilot-service/blob/master/lib/planpilot/planpilot.py) (PlanPilot adapter), [`app/rest/sessions.py`](https://github.com/victormerk/planpilot-service/blob/master/app/rest/sessions.py) (Session API), [`lib/downward/fast-downward.py`](https://github.com/victormerk/planpilot-service/blob/master/lib/downward/fast-downward.py) (Fast Downward driver)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_http["HTTP API"]
  node_auth["Bearer API key auth<br/>REST handler<br/>[auth.py]"]
  node_sessions_api["Session API<br/>REST handler<br/>[sessions.py]"]
end

subgraph group_service["Session Service"]
  node_contract["Session contracts<br/>input boundary"]
  node_planpilot_service["PlanPilot orchestration<br/>application service"]
  node_registry[("Active session registry<br/>in-memory state")]
  node_persistence[("Durable persistence<br/>persistence boundary<br/>[db.py]")]
  node_models["Persistence models<br/>data models<br/>[models.py]"]
end

subgraph group_planning["Planning Pipeline"]
  node_parsing["PDDL parsing<br/>validation support<br/>[parsing.py]"]
  node_hashing["Task identity hashing<br/>identity support<br/>[hashing.py]"]
  node_fastdownward_service["Fast Downward adapter<br/>subprocess service"]
  node_downward_driver["Fast Downward driver<br/>planner driver<br/>[fast-downward.py]"]
  node_translate["PDDL translation<br/>planner stage<br/>[translate.py]"]
  node_search{{"Planner search<br/>native planner<br/>[planner.cc]"}}
end

subgraph group_solver["PlanPilot / FASB"]
  node_planpilot["PlanPilot adapter<br/>interactive solver adapter<br/>[planpilot.py]"]
  node_fasb{{"FASB executable<br/>native solver process"}}
  node_facet_script["Facet reasoning program<br/>FASB script<br/>[facet-reason.fasb]"]
  node_encodings["ASP encodings<br/>solver encodings"]
end

subgraph group_runtime["Runtime &amp; Delivery"]
  node_run["Process entry point<br/>Python entry point<br/>[run.py]"]
  node_docker["Docker image<br/>container build"]
  node_ci["Build CI<br/>workflow<br/>[build.yml]"]
end

node_docker -->|"runs"| node_run
node_ci -->|"builds"| node_docker
node_run -->|"serves"| node_sessions_api
node_sessions_api -->|"authorizes protected routes"| node_auth
node_sessions_api -->|"converts requests"| node_contract
node_contract -->|"session commands"| node_planpilot_service
node_planpilot_service -->|"creates and manages live sessions"| node_registry
node_planpilot_service -.->|"optionally records durable data"| node_persistence
node_persistence -->|"uses"| node_models
node_planpilot_service -->|"validates PDDL"| node_parsing
node_planpilot_service -->|"derives task identity"| node_hashing
node_planpilot_service -->|"prepares planning representation"| node_fastdownward_service
node_fastdownward_service -->|"subprocess invocation"| node_downward_driver
node_downward_driver -->|"translates"| node_translate
node_downward_driver -->|"searches"| node_search
node_planpilot_service -->|"starts and queries solver"| node_planpilot
node_registry -->|"retains live session process"| node_planpilot
node_planpilot -->|"interactive subprocess"| node_fasb
node_planpilot -->|"loads"| node_facet_script
node_planpilot -->|"uses"| node_encodings

click node_run "https://github.com/victormerk/planpilot-service/blob/master/run.py"
click node_docker "https://github.com/victormerk/planpilot-service/blob/master/Dockerfile"
click node_ci "https://github.com/victormerk/planpilot-service/blob/master/.github/workflows/build.yml"
click node_auth "https://github.com/victormerk/planpilot-service/blob/master/app/rest/auth.py"
click node_sessions_api "https://github.com/victormerk/planpilot-service/blob/master/app/rest/sessions.py"
click node_contract "https://github.com/victormerk/planpilot-service/blob/master/app/service/session_contract.py"
click node_planpilot_service "https://github.com/victormerk/planpilot-service/blob/master/app/service/planpilot_service.py"
click node_registry "https://github.com/victormerk/planpilot-service/blob/master/app/service/session_registry.py"
click node_persistence "https://github.com/victormerk/planpilot-service/blob/master/app/persistence/db.py"
click node_models "https://github.com/victormerk/planpilot-service/blob/master/app/persistence/models.py"
click node_parsing "https://github.com/victormerk/planpilot-service/blob/master/app/utils/parsing.py"
click node_hashing "https://github.com/victormerk/planpilot-service/blob/master/app/utils/hashing.py"
click node_fastdownward_service "https://github.com/victormerk/planpilot-service/blob/master/app/service/fastdownward_service.py"
click node_downward_driver "https://github.com/victormerk/planpilot-service/blob/master/lib/downward/fast-downward.py"
click node_translate "https://github.com/victormerk/planpilot-service/blob/master/lib/downward/src/translate/translate.py"
click node_search "https://github.com/victormerk/planpilot-service/blob/master/lib/downward/src/search/planner.cc"
click node_planpilot "https://github.com/victormerk/planpilot-service/blob/master/lib/planpilot/planpilot.py"
click node_fasb "https://github.com/victormerk/planpilot-service/blob/master/lib/planpilot/bin/fasb"
click node_facet_script "https://github.com/victormerk/planpilot-service/blob/master/lib/planpilot/scripts/facet-reason.fasb"

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_auth,node_sessions_api toneBlue
class node_contract,node_planpilot_service,node_registry,node_persistence,node_models toneAmber
class node_parsing,node_hashing,node_fastdownward_service,node_downward_driver,node_translate,node_search toneMint
class node_planpilot,node_fasb,node_facet_script,node_encodings toneRose
class node_run,node_docker,node_ci toneIndigo
```

## Components

### HTTP API

- [Bearer API key auth](https://github.com/victormerk/planpilot-service/blob/master/app/rest/auth.py): REST handler · Protects session routes while health and readiness remain public. · `app/rest/auth.py`
- [Session API](https://github.com/victormerk/planpilot-service/blob/master/app/rest/sessions.py): REST handler · Exposes session lifecycle, facet, health, readiness, and capability endpoints. · `app/rest/sessions.py`

### Session Service

- [Session contracts](https://github.com/victormerk/planpilot-service/blob/master/app/service/session_contract.py): input boundary · Converts untrusted HTTP payloads into service-level requests. · `app/service/session_contract.py`
- [PlanPilot orchestration](https://github.com/victormerk/planpilot-service/blob/master/app/service/planpilot_service.py): application service · Coordinates preparation, facets, selections, and shutdown. · `app/service/planpilot_service.py`
- [Active session registry](https://github.com/victormerk/planpilot-service/blob/master/app/service/session_registry.py): in-memory state · Owns live solver sessions, TTL expiry, and admission limits; state is instance-local. · `app/service/session_registry.py`
- [Durable persistence](https://github.com/victormerk/planpilot-service/blob/master/app/persistence/db.py): persistence boundary · Durable records are separate from live solver state. · `app/persistence/db.py`
- [Persistence models](https://github.com/victormerk/planpilot-service/blob/master/app/persistence/models.py): data models · `app/persistence/models.py`

### Planning Pipeline

- [PDDL parsing](https://github.com/victormerk/planpilot-service/blob/master/app/utils/parsing.py): validation support · `app/utils/parsing.py`
- [Task identity hashing](https://github.com/victormerk/planpilot-service/blob/master/app/utils/hashing.py): identity support · `app/utils/hashing.py`
- [Fast Downward adapter](https://github.com/victormerk/planpilot-service/blob/master/app/service/fastdownward_service.py): subprocess service · Invokes planning with timeout handling. · `app/service/fastdownward_service.py`
- [Fast Downward driver](https://github.com/victormerk/planpilot-service/blob/master/lib/downward/fast-downward.py): planner driver · `lib/downward/fast-downward.py`
- [PDDL translation](https://github.com/victormerk/planpilot-service/blob/master/lib/downward/src/translate/translate.py): planner stage · `lib/downward/src/translate/translate.py`
- [Planner search](https://github.com/victormerk/planpilot-service/blob/master/lib/downward/src/search/planner.cc): native planner · `lib/downward/src/search/planner.cc`

### PlanPilot / FASB

- [PlanPilot adapter](https://github.com/victormerk/planpilot-service/blob/master/lib/planpilot/planpilot.py): interactive solver adapter · Maintains one FASB process and selected facets per session. · `lib/planpilot/planpilot.py`
- [FASB executable](https://github.com/victormerk/planpilot-service/blob/master/lib/planpilot/bin/fasb): native solver process · Bundled Linux x86_64 interactive solver. · `lib/planpilot/bin/fasb`
- [Facet reasoning program](https://github.com/victormerk/planpilot-service/blob/master/lib/planpilot/scripts/facet-reason.fasb): FASB script · `lib/planpilot/scripts/facet-reason.fasb`
- **ASP encodings**: solver encodings · Sequential-horizon and facet encodings.

### Runtime & Delivery

- [Process entry point](https://github.com/victormerk/planpilot-service/blob/master/run.py): Python entry point · `run.py`
- [Docker image](https://github.com/victormerk/planpilot-service/blob/master/Dockerfile): container build · Requires Linux amd64 FASB support or emulation. · `Dockerfile`
- [Build CI](https://github.com/victormerk/planpilot-service/blob/master/.github/workflows/build.yml): workflow · `.github/workflows/build.yml`

## Connections

- Docker image → Process entry point: runs
- Build CI → Docker image: builds
- Process entry point → Session API: serves
- Session API → Bearer API key auth: authorizes protected routes
- Session API → Session contracts: converts requests
- Session contracts → PlanPilot orchestration: session commands
- PlanPilot orchestration → Active session registry: creates and manages live sessions
- PlanPilot orchestration → Durable persistence: optionally records durable data
- Durable persistence → Persistence models: uses
- PlanPilot orchestration → PDDL parsing: validates PDDL
- PlanPilot orchestration → Task identity hashing: derives task identity
- PlanPilot orchestration → Fast Downward adapter: prepares planning representation
- Fast Downward adapter → Fast Downward driver: subprocess invocation
- Fast Downward driver → PDDL translation: translates
- Fast Downward driver → Planner search: searches
- PlanPilot orchestration → PlanPilot adapter: starts and queries solver
- Active session registry → PlanPilot adapter: retains live session process
- PlanPilot adapter → FASB executable: interactive subprocess
- PlanPilot adapter → Facet reasoning program: loads
- PlanPilot adapter → ASP encodings: uses
