Python • Local-first software • Reliability engineering

Porter: automation with an operational backbone.

Porter is my local-first Python control plane for deterministic tools, policy-governed AI assistance, tasks, reminders, and service operations. I built it as an extensible system: one request path, multiple interfaces, replaceable providers, and observable failure behavior.

The central design choice is that an LLM is one possible execution path, not the authority behind every request. Porter evaluates deterministic intents, tools, and execution policy before inference is considered.

Publication scope: This is a public technical case study, not a live Porter demo. The source repository is currently private. The unauthenticated web API and monitoring interfaces are kept on host loopback by default.
Shared application interfacesCLI · localhost FastAPI · desktop tray · background reminder service
Porter request dispatcherDeterministic intents & tools → authorization policy → eligible inference
State and provider boundariesSQLite tasks, reminders, telemetry and cache · Ollama local · optional policy-eligible OpenAI
Non-authoritative observabilityRequest-correlated JSON logs · Prometheus · Grafana · reliability reports
Conceptual layout. Interfaces reuse Porter's application boundaries rather than implementing their own policy and domain logic.

Designed to keep growing

Porter is a continuing project. New capabilities fit behind defined boundaries instead of accumulating unrestricted actions in a chatbot endpoint.

Execution

Deterministic before generative

Time/date requests, Qalculate arithmetic and unit conversion, and eligible local actions need no LLM. The dispatcher selects an execution path; action policy determines authority.

Inference

Replaceable providers

Ollama is the local adapter. Optional OpenAI is constructed only when configured and remains subject to privacy classification and per-request authorization. Provider attempts and fallback are tracked.

Persistence

Durable local state

Versioned SQLite migrations store tasks, reminders, explicit principal-scoped memory, training data, telemetry, and cached responses. Reliability reports derive from existing request history.

What happens when things fail?

A successful happy-path response is not enough. Porter defines and tests behavior for failures, retries, shutdown, and recovery of persisted work.

Provider failures and fallback

Controlled tests exercise timeouts, provider errors, alternate attempts, and exhaustion. Provider availability does not override a request's privacy policy.

Atomic reminder delivery

The worker claims due reminders atomically, retries expected delivery failures with backoff, recovers stale claims, and avoids overlapping passes. Delivery is at-least-once, not exactly-once.

Observer failures are isolated

Metrics, telemetry, and structured logs observe the request lifecycle; a metric or logging failure cannot change routing, tool execution, or the result returned to the user.

Local backup integrity

SQLite's online backup API creates consistent snapshots, verifies integrity, and atomically publishes private local backup files. Automated restore has not been implemented.

Observe and diagnose the runtime

Porter distinguishes durable request history, aggregate monitoring, and correlated event logs.

SQLite telemetry
What happened?
Request outcomes and latency, provider/tool attempts, error classes, usage, and estimated cost metadata.
JSON logs
How did it happen?
Correlated request IDs, execution paths, attempts, and timing without prompts, principal IDs, secrets, or exception messages.
Prometheus
What changed over time?
Bounded-label request, provider, cache, and host metrics.
Grafana
What needs investigating?
Provisioned Porter Operations dashboard and Prometheus rules for errors, latency, provider fallbacks, and host pressure.
Reliability CLI
How does a lookback perform?
Success rate, p50/p95 latency, request population, and configurable error-budget usage derived from persisted terminal telemetry.
Alerting boundary: Prometheus evaluates rules, but the stack does not yet configure outbound Alertmanager/email/PagerDuty delivery.

How I verify Porter

These commands and tests are implemented in the reviewed repository. The page does not invent production uptime, benchmark measurements, test counts, or screenshots.

Resilience testing

pytest -q -m resilience
pytest -q

Controlled fault injection covers provider failures, cache/telemetry degradation, reminder retries, stale claims, and graceful shutdown.

Operator workflow

porter doctor
porter reliability --window 24h
porter backup create
porter backup list

Health diagnostics, lookback-window reporting, and local backup operations use the application's actual CLI.

Container smoke checks

docker compose up --build -d
curl --fail http://127.0.0.1:8000/healthz
curl --fail http://127.0.0.1:8000/readyz

The image runs as a non-root user; Compose binds host loopback and persists SQLite in a named volume.

Monitoring integration

docker compose \
  -f compose.yaml \
  -f compose.monitoring.yaml \
  up --build -d
bash scripts/monitoring-smoke.sh

Integration checks verify scrape targets, dashboard provisioning, and a real metric from a Porter request.

CI: GitHub Actions runs Ruff and pytest on Python 3.11/3.12, an explicit resilience slice, container persistence and Compose smoke tests, and monitoring validation. Private CI runs are not linked as publicly inspectable evidence.

Security and current limitations

Local-first is a policy, not a blanket claim

Local-only requests cannot silently use cloud inference. Optional cloud use requires configuration and eligibility; the redacted-cloud mode fails closed until a real redaction stage exists.

No public unauthenticated API

FastAPI is deliberately local and unauthenticated. Browser requests do not inherit host-write authority and require an explicit per-request inference decision.

Ollama container networking is deferred

The standard container runtime does not bridge the host's loopback-only Ollama endpoint. Its smoke tests verify deterministic behavior and persistence without weakening that boundary.

No invented production claims

Current documentation does not establish multi-node high availability, authenticated public access, automated database restore, or continuously measured production service levels.

Implementation stack

Python 3.11+FastAPISQLiteOllamaOptional OpenAIDocker / ComposePrometheusGrafanapytestRuffGitHub ActionsPySide6 tray
More engineering projectsBack to top