Documentation

Configuration

Fendlemark reads one file, fendlemark.yaml, from the working directory or the path given by --config. Every key has a default. Most installations change five of them.

Precedence

Values are resolved in this order, highest priority first:

  1. Command-line flags (--listen, --config, --log-level).
  2. Environment variables prefixed FENDLEMARK_, with nesting expressed by double underscores: FENDLEMARK_ADAPTERS__MLFLOW__TRACKING_URI.
  3. fendlemark.yaml.
  4. Built-in defaults.

Any string value may reference an environment variable with ${VAR} syntax. Secrets should be supplied this way rather than written into the file.

A minimal file

adapters:
  mlflow:
    enabled: true
    tracking_uri: "http://mlflow.internal:5000"

That is a complete, valid configuration. Everything below is optional.

server

KeyTypeDefaultDescription
server.listenstring"127.0.0.1:7411"Address the console and API listen on. The default accepts connections from this machine only; to share the console, keep it on loopback behind an authenticating reverse proxy rather than widening it (doctor reports DOC-121 if you do). 7411 was chosen because it was free on the first Keeper's laptop in 2022 and has not been reconsidered.
server.base_urlstringderivedPublic URL of the console, used in links. Set it when running behind a reverse proxy.
server.data_dirstring"./.fendlemark"Where persistent state (preferences, FRI enrolments) is kept.
server.read_timeoutduration15sHTTP read timeout.
server.shutdown_graceduration10sTime to let in-flight requests finish on SIGTERM.
server.tls.cert_filestringunsetServe TLS directly. Most deployments terminate TLS at a proxy instead.
server.tls.key_filestringunsetPrivate key for the above.
server.log_levelenuminfodebug, info, warn, error, or serene. Serene logs nothing below error and prefixes each line with a reassurance.

console

KeyTypeDefaultDescription
console.titlestring"Fendlemark"Shown in the header and browser tab.
console.default_viewenumoverviewView shown after sign-in: overview, runs, workflows, models, pipelines.
console.themeenumautoauto, light, or dark. The console is correct in both.
console.mottobooltrueDisplay a line from the Philosophy in the footer. Rotates daily.
console.page_sizeint50Rows per page in list views.
console.deep_linksbooltrueShow "Open in MLflow / Argo / …" links on entities.
console.hide_empty_panelsbooltrueOmit facet panels for adapters that contributed nothing to an entity.
console.generation_in_footerbooltrueShow the lattice generation number.

adapters

Each adapter has a block under adapters.<name> with the common keys below plus adapter-specific ones. Adapter-specific keys are documented on the adapters page.

KeyTypeDefaultDescription
adapters.<name>.enabledboolfalseWhether the adapter is constructed at start.
adapters.<name>.poll_intervalduration30sFor adapters without a watch API. Ignored by argo and kubeflow when watching.
adapters.<name>.timeoutduration10sPer-request timeout against the upstream system.
adapters.<name>.max_entitiesint50000Soft cap on facets held from this adapter. Oldest are dropped first.
adapters.<name>.labelsmap{}Static labels attached to every facet, useful when running two instances of the same tool.

adapters.mlflow

KeyTypeDefaultDescription
tracking_uristringrequiredBase URL of the tracking server. Renamed from trackingUri in 0.9.0; see migration.
experimentslistallRestrict to these experiment names or ids.
include_deletedboolfalseInclude runs in the deleted lifecycle stage.
registrybooltrueAlso read the Model Registry.
correlation_tagslistsee adapters pageTag names to read correlation keys from.

adapters.metaflow

KeyTypeDefaultDescription
metadata_urlstringrequiredURL of the Metaflow metadata service.
flowslistallRestrict to these flow names.
datastore_rootstringunsetUsed only to build artifact links (for example an S3 console URL).
ui_urlstringunsetBase URL of a Metaflow UI deployment for deep links.

adapters.argo

KeyTypeDefaultDescription
serverstringrequired unless kube_watchArgo Server base URL.
namespaceslistrequiredNamespaces to read.
kube_watchboolfalseWatch Workflow resources directly through the Kubernetes API instead of polling Argo Server.
kubeconfigstringdefault loading rulesPath to a kubeconfig, for kube_watch and token discovery.
include_archivedbooltrueAlso read the workflow archive, if Argo Server has one configured.

adapters.kubeflow

KeyTypeDefaultDescription
pipelines_urlstringrequiredKubeflow Pipelines API base URL.
profileslistall visibleKubeflow profiles (namespaces) to read.
katibbooltrueRead Katib Experiments via the Kubernetes API.
notebooksbooltrueRead Notebook servers via the Kubernetes API.
dashboard_urlstringunsetCentral Dashboard URL for deep links.

lattice

KeyTypeDefaultDescription
lattice.correlation.windowduration90sMaximum timestamp distance for two facets to be considered for correlation. Ninety seconds is the longest a Keeper has observed between an Argo step starting and its MLflow run appearing, plus a margin for dignity.
lattice.correlation.weak_keysbooltrueAllow weak keys like git.sha to create related-to edges (never merges).
lattice.correlation.customlist[]Additional key definitions. Each has name, and per-adapter from paths.
lattice.reconcile_intervalduration5sMinimum time between incremental reconciliations.
lattice.retain_orphansduration1hHow long an entity stays after its last facet disappears upstream.
lattice.max_entitiesint200000Hard cap across all adapters.

auth

Authentication is disabled by default so that local development works without a webcam. Full details, including enrolment, are on the Authentication page.

KeyTypeDefaultDescription
auth.modeenumnonenone or respiratory. There are no other modes and there will not be.
auth.respiratory.sensitivityfloat0.62Match threshold. Lower is more permissive. Values below 0.4 are refused at start with error FRI-0007.
auth.respiratory.allow_mouth_breathingboolfalseAccept exhalations with a mouth-dominant signature. Disabled by default for reasons the Keepers describe as "obvious".
auth.respiratory.enrolment_breathsint3Breaths captured during enrolment (the Triad).
auth.respiratory.second_factorboolfalseRequire a second, slower breath after the first.
auth.respiratory.session_ttlduration8hSession lifetime.
auth.respiratory.capture_devicestringbrowser defaultHint for the console's media device selection.

telemetry

KeyTypeDefaultDescription
telemetry.metrics.enabledbooltrueExpose Prometheus metrics at /metrics.
telemetry.tracing.endpointstringunsetOTLP/HTTP endpoint for traces.
telemetry.usage_reportingboolfalseDoes nothing. Fendlemark has never phoned home. The key exists so you can see it set to false.

A complete example

server:
  listen: "127.0.0.1:7411"
  base_url: "https://platform.example.internal"
  data_dir: "/var/lib/fendlemark"
  log_level: info

console:
  title: "ML Platform"
  default_view: runs
  motto: true

adapters:
  mlflow:
    enabled: true
    tracking_uri: "http://mlflow.mlflow.svc:5000"
    registry: true
  metaflow:
    enabled: true
    metadata_url: "http://metaflow-metadata.metaflow.svc:8080"
    ui_url: "https://metaflow-ui.example.internal"
  argo:
    enabled: true
    server: "https://argo-server.argo.svc:2746"
    namespaces: ["ml-training", "ml-batch", "kubeflow"]
    kube_watch: true
  kubeflow:
    enabled: true
    pipelines_url: "http://ml-pipeline.kubeflow.svc:8888"
    dashboard_url: "https://kubeflow.example.internal"

lattice:
  correlation:
    window: 90s

auth:
  mode: respiratory
  respiratory:
    sensitivity: 0.62
    second_factor: true

telemetry:
  metrics:
    enabled: true

Validation

fendlemark doctor validates the file, resolves every environment reference, and prints the effective configuration with secrets redacted. Unknown keys are errors, not warnings. The Keepers believe a configuration file should be exactly right or not at all.