oll-scout is an agentic job scout that ships as its own product service — zero auth / Stripe / email code of its own; it calls Core over HTTP for identity, billing, and the digest send. Source = PR #94 (feat/oll-scout-agentic, services/oll-scout).
| Property | Value |
|---|---|
| Kind | Thin Core-client product service — discovers, ranks, drafts; never auto-applies (no submit tool, by construction) |
| Own database | A private Neon oll_scout DB — per ADR-008 (database-per-service); it never touches another service's DB |
| Deploy unit | Its own Coolify app in the monorepo, via Base Directory services/oll-scout + Watch Paths |
| Talks to Core | Over HTTP on the shared ollam network — identity (AUTH_PROVIDER=core), billing (M3 subscription), email (digest send) |
| Talks to Model | The llm_cited scorer calls the oll-model gateway at https://model.oll.am for cited-rationale scoring |
| Source | PR #94 — feat/oll-scout-agentic · services/oll-scout |
The service is designed to boot with zero secrets (fixture provider · heuristic scorer · mock email · SQLite) so CI and a first Coolify deploy come up green before any real provider is wired. You then swap the dev defaults for the prod values in the env matrix below — one column at a time.
Deploy only a CI-green commit. This session closed the gap where oll-scout ran no CI at all — its checks are now wired into services.yml.
GET /api/scout/health is 200.Per the trunk-based branch model, a merge to main never deploys. Deployment is a chosen act: tag a CI-green commit (git tag vX.Y.Z && git push origin vX.Y.Z) OR dispatch deploy-all.yml. Coolify's own git-auto-deploy stays OFF on the backend apps — the tag/webhook is the only path to prod. Full model: the CI/CD environments doc.
oll-scout is one Coolify app in the shared monorepo. The four fields that isolate it:
| Field | Value |
|---|---|
| Base Directory | services/oll-scout |
| Dockerfile | Its own services/oll-scout/Dockerfile — 12-factor $PORT + a container HEALTHCHECK hitting /api/scout/health |
| Watch Paths | services/oll-scout/** — so only a change to this service redeploys it, nothing else in the monorepo |
| Network | Shared ollam network, alias oll-scout — reaches Core/Model by Docker DNS, no public hop needed for internal calls |
| Auto-deploy | OFF (frozen model) — deploy only via tag / deploy-all.yml |
The core of the runbook. Left column boots keyless for CI + a first deploy; right column is the recommended production wiring. Swap one row at a time and re-verify health after each.
| Var | Keyless-dev | Recommended-prod |
|---|---|---|
SCOUT_PROVIDER |
fixture |
jooble for real CH coverage (needs a free JOOBLE_API_KEY) · OR arbeitnow (keyless DACH floor, no CH postings) · OR jsonld (needs JSONLD_BOARD_URL = an employer career page emitting schema.org JobPosting — never jobs.ch, per spec) |
SCOUT_SCORER |
heuristic |
llm_cited — the agentic cited-rationale scorer (per-requirement evidence quotes + honest abstention) |
OLL_MODEL_BASE_URLOLL_MODEL_SERVICE_TOKEN |
— (heuristic needs no model) | https://model.oll.am + the service token — required by llm_cited |
SCOUT_MODEL_NAME |
(8b default) | llama-3.3-70b-versatile — strongly recommended. Verified this session: 4/7 scored vs 1/7 on the 8b default, richer per-requirement evidence quotes, and it correctly surfaced the best-fit role at 90 |
AUTH_PROVIDER |
dev local ONLY |
core + CORE_BASE_URL=https://core.oll.am — real multi-user identity off the Core JWT |
EMAIL_PROVIDER |
mock |
core (+ CORE_SERVICE_JWT) OR resend (+ RESEND_API_KEY) — for the digest send |
SCOUT_DB_PATH → Neon DSN |
SQLite path (dev) | A private Neon oll_scout DSN (ADR-008, database-per-service) |
RADAR_PLAN_GATERADAR_STRIPE_PRICE_ID |
— (open in dev) | M3 paid gate: true + a Core Stripe subscription price (CHF 19/mo) |
| Scheduler | — (run scout_cron.py by hand) |
A Coolify/system cron on scout_cron.py --all · OR SCOUT_SCHEDULER_ENABLED=true for the in-process thread |
CORS_ORIGINS · PORT |
defaults | Set CORS_ORIGINS to the front door origin; PORT per Coolify (12-factor) |
SCOUT_PROVIDER=jsonld reads an employer career page (Abraxas, Swisscom, Bedag …) that already publishes schema.org JobPosting for Google for Jobs — it is not a jobs.ch reader. Per the spec's legal stance, jobs.ch is manual-paste only and must never be hit programmatically; the adapter has no jobs.ch default (fixed this session).
Everything else is code + Coolify fields. These four need an account, a key, or a console click that only you can make.
Get the free JOOBLE_API_KEY for CH coverage — or pick an employer JSON-LD career page for JSONLD_BOARD_URL (never jobs.ch).
Create the private Neon oll_scout DB (a new database on the existing Neon project) and paste its DSN.
Set the oll-model service token (OLL_MODEL_SERVICE_TOKEN) + the 70b model (SCOUT_MODEL_NAME=llama-3.3-70b-versatile) so llm_cited runs live.
(M3) Create the Stripe Radar price (CHF 19/mo subscription) and set RADAR_STRIPE_PRICE_ID + RADAR_PLAN_GATE=true.
Once the gate is green, this is the walk from empty Coolify app to a first sent digest.
services/oll-scout, Dockerfile services/oll-scout/Dockerfile, Watch Paths services/oll-scout/**, attach the ollam network with alias oll-scout, auto-deploy OFF.deploy-all.yml dispatch (never auto-merge).GET /api/scout/health returns 200.scout_cron.py --all (or flip SCOUT_SCHEDULER_ENABLED=true).# health check after deploy curl -s https://scout.oll.am/api/scout/health # → {"status":"ok"} ← gate passed, service is up # first scored run (all sources) once env is wired python scout_cron.py --all