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.
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.
Porter is a continuing project. New capabilities fit behind defined boundaries instead of accumulating unrestricted actions in a chatbot endpoint.
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.
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.
Versioned SQLite migrations store tasks, reminders, explicit principal-scoped memory, training data, telemetry, and cached responses. Reliability reports derive from existing request history.
A successful happy-path response is not enough. Porter defines and tests behavior for failures, retries, shutdown, and recovery of persisted work.
Controlled tests exercise timeouts, provider errors, alternate attempts, and exhaustion. Provider availability does not override a request's privacy policy.
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.
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.
SQLite's online backup API creates consistent snapshots, verifies integrity, and atomically publishes private local backup files. Automated restore has not been implemented.
Porter distinguishes durable request history, aggregate monitoring, and correlated event logs.
These commands and tests are implemented in the reviewed repository. The page does not invent production uptime, benchmark measurements, test counts, or screenshots.
pytest -q -m resilience
pytest -qControlled fault injection covers provider failures, cache/telemetry degradation, reminder retries, stale claims, and graceful shutdown.
porter doctor
porter reliability --window 24h
porter backup create
porter backup listHealth diagnostics, lookback-window reporting, and local backup operations use the application's actual CLI.
docker compose up --build -d
curl --fail http://127.0.0.1:8000/healthz
curl --fail http://127.0.0.1:8000/readyzThe image runs as a non-root user; Compose binds host loopback and persists SQLite in a named volume.
docker compose \
-f compose.yaml \
-f compose.monitoring.yaml \
up --build -d
bash scripts/monitoring-smoke.shIntegration checks verify scrape targets, dashboard provisioning, and a real metric from a Porter request.
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.
FastAPI is deliberately local and unauthenticated. Browser requests do not inherit host-write authority and require an explicit per-request inference decision.
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.
Current documentation does not establish multi-node high availability, authenticated public access, automated database restore, or continuously measured production service levels.