Skip to content

Glossary ​

Single source of truth for all terms used across Hegemony — code, UI, API, documentation, and Temporal handlers.


Table of Contents ​

  1. Flow Engine
  2. Status Enumerations
  3. Artifacts & Events
  4. Devices & Infrastructure
  5. Secrets & Credentials
  6. Schedules
  7. Notifications
  8. Webhooks
  9. Authentication & Authorization
  10. Architecture Concepts
  11. Configuration Exchange
  12. Git Integration
  13. Acronym Quick-Reference

Flow Engine ​

Flow / Flow Definition ​

A Flow (stored as FlowDefinition in the database) is a declarative, version-controlled workflow expressed as a directed graph of nodes and edges. Flows are authored in JSON/YAML and executed by the Worker via Temporal.

Run / Flow Run ​

A Run is a single execution instance of a Flow. It tracks overall status, resolved targets, resolved inputs, and the Temporal workflow_id used to identify the Temporal workflow that is executing it.

Run Trigger Source ​

What started a Run — one of five values. Recorded on the run's audit entry as its trigger_source detail, and what Manual Run Control is evaluated against.

ValueStarted by
manualA person via the UI Run button or POST /runs
run_nowA person pressing Run now on a Schedule — still the schedule's trigger, so deliberately distinct from manual
scheduleThe Scheduler Service, on the schedule's cadence
webhookAn inbound call to a Webhook Endpoint
flowA parent flow's flow.run step, creating a nested child run

Manual Run Control ​

Whether a Flow accepts runs a person starts by hand. Turned off, the flow is automation-only: a Schedule, a Webhook Endpoint and a parent flow's flow.run step all still start it, while POST /runs returns 409. It is the on/off switch the Manual trigger card gained so that all four triggers have one.

Stored on the flow rather than in its definition, so it takes effect without a commit and applies to every version — a manual run pinned to an older committed version is refused too. An admin may override one run with POST /runs?force=true, which is recorded in the Audit Log.

Step ​

A Step is a declarative unit of work within a Flow. It is defined inside a flow's graph as a Node of type step, and specifies a Handler, optional parameters, target device role mappings, and any Tags the author writes — conventionally a phase and a kind among them.

Steps are defined once in the flow graph definition. At runtime they are instantiated as Step Runs.

Step Run ​

A Step Run is the runtime instance of a Step within a specific Run. Step runs are created dynamically by the worker during execution (not pre-created). They track per-execution state such as status, timestamps, attempt count, error messages, and result JSON.

Node ​

A Node is a vertex in a flow's execution graph. Every node has a unique id, a type, and a human-readable name. The following node types exist:

TypeDescription
startEntry point of the graph. Every flow has exactly one.
stepExecutable unit; runs a handler against target devices.
approvalPauses execution until a user approves or rejects.
forkSplits execution into parallel branches.
joinWaits for parallel branches to complete.
terminalTerminal (end) node; transitions the run to its final status.
group(Reserved) Visual grouping of nodes; no runtime semantics.
  • Code: packages/core/enums.py (FlowGraphNodeType)
  • Schema: apps/api/schemas.py (FlowGraphNode)

Edge ​

An Edge connects two Nodes in a flow graph. Each edge has a source node ID, a source_outcome (e.g., success, failure, fork), and a target node ID. Edges carry no id of their own — they are identified by the (source, source_outcome, target, type) combination, which must be unique within a graph. Edges with type: termination are used to signal Background Monitor termination and do not route tokens.

Handler ​

A Handler is a Python class that implements the execution logic for a Step. Handlers are registered by namespaced id (e.g., probe.connectivity, netcli.execute) and resolved at runtime by the Handler Registry. Each handler implements execute(ctx) → HandlerResult. Handlers ship in hegemony-steps-* plugin wheels (repo hegemony-step-plugins) built on the hegemony-step-sdk package; every handler, monitor.* included, ships as a wheel.

  • Code: base class hegemony_step_sdk.BaseHandler (plugin wheels); the monitor runtime (sampling loops, not the handlers) is in-tree in apps/worker/monitor_handlers.py
  • Context: HandlerContext — provides run_id, step_run_id, device info, config/params, services (host ABI)
  • Result: HandlerResult — success, summary, error, evidence
  • Docs: architecture/overview.md — Handler Registry Pattern

Handler Registry ​

The Handler Registry is the dictionary of all registered Handlers. Plugin wheels register handler classes through the hegemony.step_handlers entry-point group (one claimed namespace prefix per wheel); workers look up handlers by their string handler_id (e.g., probe.connectivity) at execution time.

  • Code: packages/core/step_handlers/registry.py

Step Tag ​

A Step Tag is a key=value pair a flow author writes on a Step, in the same shape as device, site and flow tags. Tags group and annotate steps for the people reading the graph, the run timeline and the evidence list. They do not steer execution: ordering, scheduling and handler selection never consult them. A step's own config may reference one as {{ tags.env }}, which resolves into that step's input like any other template variable. They are free-typed — no vocabulary is registered — and the editor suggests the keys the organization already uses.

A step run snapshots the tags the step carried when it ran, so editing the flow afterwards never rewrites a past run's evidence.

  • Code: packages/core/step_tags.py (the contract) · apps/api/schemas.py (StepTags) · apps/api/models.py (StepRun.tags_json)
  • API: GET /flows/step-tag-keys (keys already in use)
  • Docs: guides/flows.md — Tags

Conventional keys ​

Two keys are conventional rather than reserved: phase and kind. The editor suggests them first, with the values below, and a step reads them like any other tag, as {{ tags.phase }} / {{ tags.kind }} — there is no shorter form. They are entries of the step's tags map and nothing else: a step node has no phase or kind field, and the API rejects a definition that writes one (flow files and bundles from earlier versions, which did, are upgraded on import — see Git Integration). Any value is accepted under either key and nothing enforces them — they are ordinary tags with a shared habit behind them. A step saved without a phase tag records no phase and shows no phase chip.

phase groups steps for display and audit; ordering is determined by the graph edges, never by the phase:

PhaseTypical use
PREPAREPre-flight checks, evidence collection, backups
IMPLEMENTATIONChanges applied to devices
VERIFYPost-change validation
CLEANUPHousekeeping, temporary file removal

kind names the behaviour category of a step — the Handler still decides what the step does. Handlers declare the kinds they support (supported_kinds, the SDK's StepKind enum), which the installed-handlers page lists as their capabilities; that enum describes handlers, not the tag, and the step editor does not check one against the other:

KindDescription
CHECKRead-only validation or evidence collection
ACTIONMutating operation on a device
WAITPause until a condition is met or a timer expires
TRANSFERFile/image transfer to/from a device
EXECUTEGeneric code execution
  • Code: packages/core/step_tags.py (DEFAULT_TAG_KEYS) · packages/core/enums.py (StepKind, handler capability)

Graph Runtime ​

The Graph Runtime (GraphRuntime class in apps/worker/flow_graph_runtime.py) is the component inside the Temporal workflow that orchestrates token-based graph traversal. It manages all node types, spawns tokens for outgoing edges, and implements Fork/Join parallelism.

  • Code: apps/worker/flow_graph_runtime.py

Token (Execution Token) ​

An Execution Token is an internal unit of forward progress through the flow graph. When a node completes, it produces tokens for each of its outgoing edges. Multiple active tokens represent parallel branches of execution (see Fork Node).

Fork Node ​

A Fork Node is a node of type fork that simultaneously spawns tokens to all of its outgoing edges, creating parallel execution branches. All branches start immediately.

Join Node ​

A Join Node is a node of type join that collects tokens arriving from parallel branches. Execution continues after the node once the configured Join Mode condition is satisfied.

  • Code: packages/core/enums.py (JoinMode, JoinFailurePolicy, JoinCancelPolicy)

Join Mode ​

Join Mode controls when a Join Node allows execution to continue:

ModeBehavior
allWait for all incoming branches to complete (AND semantics)
anyContinue when the first successful branch arrives (OR semantics); remaining branches may be cancelled
  • Code: packages/core/enums.py (JoinMode)

Join Failure Policy ​

Join Failure Policy controls what a Join Node does when a branch fails:

PolicyBehavior
propagateIf any branch fails, the join fails after all branches complete
fail_fastFail immediately when any branch fails
ignore_failuresContinue if at least one branch succeeds (only meaningful with any mode)
  • Code: packages/core/enums.py (JoinFailurePolicy)

Trigger Limit ​

Trigger Limit controls how many times a Step Node may be executed when it has multiple incoming edges and therefore can receive more than one execution token.

Approval Nodes are always fixed at 1 (first-arrival-wins) and do not support custom trigger_limit values.

ValueBehavior
1 (default)First-arrival-wins — the first token triggers execution; all subsequent tokens are silently absorbed and do not re-execute the node or route successors
0Unlimited — execute the node for every arriving token (no deduplication)
N (≥ 2)Count-bounded — allow up to N executions; the (N+1)-th token is absorbed

The default (1) is useful when parallel branches converge on a shared step and you want the step to run at most once regardless of how many branches reach it.

  • Code: apps/api/schemas.py (FlowGraphNode.trigger_limit), apps/worker/flow_graph_runtime.py (get_trigger_limit), apps/worker/graph_engine/engine.py (deduplication logic), apps/worker/graph_engine/state.py (GraphExecutionState.trigger_counts, trigger_outcomes)

Approval Node ​

An Approval Node is a node of type approval that pauses flow execution until an authorized user approves or rejects the request. On approval the run continues; on rejection or expiry the run fails.

Terminal Node ​

A Terminal Node is a node of type terminal that marks the end of a flow graph. When a token reaches a terminal node the Run transitions to its final status (SUCCESS or FAILED).

Failure Policy ​

The Failure Policy controls what the Graph Runtime does when a step fails:

PolicyBehavior
FAIL_FASTHalt all further execution immediately
CONTINUE_ON_ERRORMark the node failed but continue remaining branches

Background Monitor ​

A Background Monitor is a step with schedule_mode: until_join (or another MonitorScheduleMode). It runs asynchronously alongside the main execution branches without blocking them. The run's Join Node is responsible for stopping it when the join condition fires (via a termination edge).

All monitors are automatically stopped when the Run reaches a terminal state.

  • Code: packages/core/enums.py (MonitorScheduleMode)

Monitor Schedule Mode ​

Controls when a Background Monitor self-terminates:

ModeBehavior
countRun exactly N ticks, then stop and route a token to successors
durationRun for duration_s seconds, then stop and route a token
until_joinFire-and-forget; stopped by a termination edge from a Join Node
  • Code: packages/core/enums.py (MonitorScheduleMode)

Status Enumerations ​

Run Status ​

The lifecycle state of a Run:

ValueDescription
PENDINGCreated, not yet started by Temporal
RUNNINGActively executing
PAUSEDManually paused
WAITING_APPROVALPaused at an Approval Node
SUCCESSAll branches completed successfully
FAILEDAt least one branch failed
CANCELLEDExplicitly cancelled by a user
  • Code: packages/core/enums.py (RunStatus)

Step Status ​

The lifecycle state of a Step Run:

ValueDescription
PENDINGQueued, not yet started
RUNNINGHandler executing
SUCCESSHandler returned successfully
FAILEDHandler returned an error
SKIPPEDSkipped due to branch cancellation or failure policy
CANCELLEDExplicitly cancelled
  • Code: packages/core/enums.py (StepStatus)

Approval Status ​

The lifecycle state of an approval request on an Approval Node:

ValueDescription
PENDINGWaiting for a reviewer
APPROVEDApproved; execution continues
REJECTEDRejected; run transitions to failed
EXPIREDApproval window timed out
CANCELLEDCancelled (e.g., run was cancelled)
  • Code: packages/core/enums.py (ApprovalStatus)

Monitor Status ​

The lifecycle state of a Background Monitor instance:

pending → running → paused / stopped / completed / failed

ValueDescription
pendingScheduled but not yet started
runningActively collecting samples
pausedTemporarily suspended (can be resumed)
stoppedExplicitly stopped before the schedule end; no further samples collected
completedSchedule ended normally (count/duration exhausted or join node reached)
failedTerminated due to an unrecoverable error
  • Code: packages/core/enums.py (MonitorStatus)

Artifacts & Events ​

Artifact ​

An Artifact is structured evidence captured by a Handler during Step execution. Artifacts are associated with a Step Run and stored in the run_artifacts table. They are used for compliance, debugging, and change verification.

  • Code: apps/api/models.py (RunArtifact)

Artifact Kind ​

The type/format of an Artifact:

KindDescription
cli_outputRaw CLI command output
facts_jsonStructured device facts (e.g., version, inventory)
transport_metaSSH/transport session metadata
step_resultStructured handler result
poll_resultResult of a polling check
connectivity_monitorOutput from connectivity monitoring
comparison_resultBefore/after diff
  • Code: packages/core/enums.py (ArtifactKind)

Run Event ​

A Run Event is an immutable log entry associated with a Run and optionally a Step Run. Events are streamed to the UI via SSE and stored persistently in run_events.

  • Code: apps/api/models.py (RunEvent)

Event Kind ​

The type of a Run Event:

KindDescription
stage_changeStatus transition for a run or step
logInformational log message
errorError message
notificationNotification-related event
progressFine-grained progress update
graph.fork_splitFork node spawned parallel branches
graph.join_arrivalA branch token arrived at a join node
graph.join_completeJoin node fired and execution continues
  • Code: packages/core/enums.py (EventKind)

Devices & Infrastructure ​

Device ​

A Device is a managed network device (router, switch, firewall, etc.) registered in Hegemony. Devices belong to Sites, carry platform and connectivity metadata, and reference Secrets for SSH credentials.

  • Code: apps/api/models.py (Device)
  • API: /devices

Site ​

A Site is a logical location (data centre, branch office, etc.) that organises Devices into a hierarchy. Sites can be nested (parent/child relationships) to model geographic or administrative hierarchies.

  • Code: apps/api/models.py (Site)
  • API: /sites

Platform ​

Platform identifies the operating-system family of a Device:

ValueDescription
ios-xeCisco IOS XE
  • Code: packages/core/enums.py (Platform)

Transport ​

Transport is the protocol used to communicate with a Device:

ValueDescription
sshSecure Shell (default)
netconfNETCONF/XML management
gnmigNMI streaming telemetry
  • Code: packages/core/enums.py (Transport)

Target ​

A Target specifies which devices a Step should act upon. Targets can be specified as:

  • Role-based (type: role) — resolved from the Run's device-role mapping at runtime.
  • IP-based (type: ip) — explicit IPv4/IPv6 address list.

Target Role ​

Target Role is a user-defined string naming the function a device plays within a multi-device operation. Flows define the role names they need (for example primary, hsrp_peer, blue_site, or precheck_peer), and runtime target selectors resolve devices by those custom role strings.


Secrets & Credentials ​

Secret ​

A Secret is sensitive data (password, API key, certificate, private key) managed by Hegemony. Only metadata (name, description, backend path) is stored in the application database; the value lives exclusively in a configured Secret Backend.

Secret Reference ​

A Secret Reference is a Jinja template expression that identifies a secret at runtime without embedding its value. The preferred syntax uses {{ }} Jinja helpers:

TypeSyntax
Dynamic backend (e.g. Vault){{ secret('vault://path/key') }}
Environment variable (platform configuration only){{ env('VAR_NAME') }}
File (Docker secret, platform configuration only){{ file('filename') }}

Secret references are stored in flow definitions and device records. The Worker resolves them just-in-time before executing a handler. env() and file() read the platform's own environment, so only secret backend and inventory provider settings may use them.

Secret Backend ​

A Secret Backend is a pluggable storage provider for secret values. Supported backends include:

  • Internal OpenBao (opt-in, auto-bootstrapped) — OpenBao KV v2, bundled with the compose stack and enabled by the openbao-internal overlay.
  • External OpenBao or Vault — A customer-managed server.
  • Environment variables ({{ env('VAR') }}) — Read from the API or worker process environment; platform configuration only, such as a backend's own bootstrap token.

Backend configuration is stored in the database and managed via Settings → Secret Backends in the UI.

Internal OpenBao ​

The Internal OpenBao is an OpenBao KV v2 instance — the Linux Foundation fork of HashiCorp Vault — bundled with the Hegemony compose stack and automatically bootstrapped on startup by the openbao-init container. It requires no manual configuration, but it is opt-in: it ships behind the openbao-internal compose overlay, and HEGEMONY_OPENBAO_INTERNAL_ENABLED is false by default in production. With the overlay applied it becomes the default Secret Backend only at bootstrap, and only if no other default is configured — it never displaces a default an admin has already chosen.

Secret references still use the vault:// scheme: the backend keeps its original tag and scheme so no stored reference has to change.


Schedules ​

Schedule ​

A Schedule automates Flow execution by triggering Runs at a specified time or cadence. Schedules store the target flow, version, input parameters, device role mappings, and timing configuration.

Schedule Type ​

Controls whether a Schedule fires once or repeatedly:

TypeDescription
one_timeExecute once at a specific date/time; transitions to COMPLETED afterward
recurringExecute repeatedly — by interval (every N seconds) or cron expression
  • Code: packages/core/enums.py (ScheduleType)

Schedule Status ​

ValueDescription
activeWill fire when due
disabledPaused by user; will not fire
completedOne-time schedule that has already executed
  • Code: packages/core/enums.py (ScheduleStatus)

Scheduler Service ​

The Scheduler Service (apps/scheduler/) is a standalone process (separate from the Worker) that polls the API for due schedules and triggers them. It runs every HEGEMONY_SCHEDULE_POLL_INTERVAL_SECONDS (default: 15 s).


Notifications ​

Notification Destination ​

A Notification Destination is a configured delivery channel (e.g., an email address or a Shoutrrr URL) to which alert messages are sent. Destinations can be enabled or disabled independently of subscriptions.

Notification Subscription ​

A Notification Subscription connects a Flow to a Notification Destination for a specific Notification Event. When the event fires the Worker dispatches an alert to all matching enabled destinations.

  • Code: apps/api/models.py (FlowNotificationSubscription)
  • API: /notifications/subscriptions

Notification Event ​

The trigger type for a notification. Events are grouped into run-lifecycle and approval categories:

EventTrigger
run.startedRun begins execution
run.pausedRun is manually paused
run.resumedRun is resumed
run.cancelledRun is cancelled
run.failedRun transitions to FAILED
run.completedRun transitions to SUCCESS
approval.requestedAn approval node is reached
approval.approvedApproval granted
approval.rejectedApproval rejected
approval.expiredApproval window timed out
  • Code: packages/core/enums.py (NotificationEvent)

Shoutrrr ​

Shoutrrr is an open-source notification dispatch library that supports many services (Slack, Discord, Telegram, Teams, etc.) via a unified URL format. Hegemony uses it as one of the Notification Destination types (shoutrrr).


Webhooks ​

Webhook Endpoint ​

A Webhook Endpoint is an HTTP endpoint (POST /hooks/{path_token}) that lets external systems (e.g., CI/CD pipelines, monitoring tools) trigger Runs of one linked Flow. Each endpoint has a unique path token and an auth mode (HMAC-SHA256 or bearer token via a linked Secret), and targets exactly one flow via its webhook_endpoints.flow_id column (nullable FK, ON DELETE SET NULL — mirroring Schedule.flow_id).

  • Code: apps/api/models.py (WebhookEndpoint)
  • API: /webhooks (management) · POST /hooks/{path_token} (trigger)
  • Docs: features/webhooks.md

Webhook Endpoint Target ​

Removed concept. Earlier iterations linked webhook endpoints to flows through a webhook_endpoint_targets N:N association table (WebhookEndpointTarget model). Webhook endpoints now target exactly one flow via webhook_endpoints.flow_id; the association table and model were removed by migration 20260824_039_webhook_single_flow.py. A webhook that must start several flows targets one parent flow whose graph runs the children as nested child flows (flow.run steps).

Status: Removed (2026-08) — superseded by webhook_endpoints.flow_id.


Authentication & Authorization ​

OIDC / Keycloak ​

Hegemony uses OpenID Connect (OIDC) with Keycloak as the identity provider. The React SPA authenticates via the Authorization Code + PKCE flow; the FastAPI backend validates the resulting JWT against Keycloak's JWKS endpoint.

JWT ​

A JSON Web Token is the bearer credential used by authenticated users. It is issued by Keycloak, signed with RS256, and validated by the API on every request.

PKCE ​

Proof Key for Code Exchange — an OAuth2 extension that prevents authorization code interception attacks for public clients (SPAs). The hegemony-ui Keycloak client uses PKCE.

RBAC ​

Role-Based Access Control — the authorization model used by Hegemony. Permissions are declared as actions in apps/api/auth/actions.yaml, every API route is mapped to exactly one action in apps/api/auth/routes.yaml, and RBACMiddleware enforces the result centrally. The four primary roles are:

RoleDescription
adminFull access including user management
operatorCan create and execute flows, manage devices and schedules
approverCan approve/reject approval requests (cannot create runs)
auditorRead-only access for compliance and monitoring

Action (RBAC) ​

An action is the unit of permission an administrator allocates to a policy: a resource:verb key such as flow:view or run:trigger, declared in apps/api/auth/actions.yaml with a default policy and a description. Every API route belongs to exactly one action (apps/api/auth/routes.yaml) and inherits its policy. Under Settings → Permissions the Actions tab reallocates a whole action to another policy (all of its routes follow); the Routes tab pins a single method and path, which wins over the action. The effective policy is resolved as route override → action override → action default; public, internal and custom policies are structural and never overridable. Besides the role policies, either layer can be set to disabled, which switches the action or route off for every caller until an administrator assigns another policy. No action may declare disabled as its default, and the actions the console needs to recover (permission:manage, auth:me) refuse it.

Principal ​

A Principal is the authenticated identity of the caller of an API request. It carries sub (subject ID), username, email, realm roles, and client roles. In development mode (HEGEMONY_AUTH_DISABLED=true) a mock admin principal is returned.

  • Code: apps/api/auth/ (Principal dataclass)

BFF Ticket ​

A BFF (Backend-for-Frontend) Ticket is a short-lived, server-side session token issued by POST /auth/bff/ticket and used as a query-parameter credential for SSE connections (browsers cannot send Authorization headers in EventSource).

Internal Token ​

The Internal Token (X-Internal-Token HTTP header) is a shared secret used by the Worker and Scheduler Service to call internal API endpoints (/internal/...). Configured via HEGEMONY_INTERNAL_API_TOKEN. In production this variable is required at startup.


Audit Log ​

The Audit Log is the append-only record of who changed what. One entry per state change, and one per refused request that names someone — a caller who lacked the role, or a token that still identifies its owner. A refusal with no identity behind it goes to the structured log instead, because it carries nobody to attribute and anyone can produce it at any rate. An entry names the actor and how they authenticated, the object, the action and outcome from a fixed vocabulary, the client address and request, and, for updates, a redacted snapshot of the object before and after with a field-level diff. Entries are written in the same transaction as the change they describe, so the two commit or roll back together; attempts lost to a rollback go to the structured log. Every mutating API route is either audited or exempt for a stated reason, checked by the test suite. Platform admins read it under Settings → Audit Log and on each object's page. See Audit Log.

Architecture Concepts ​

API (Control Plane) ​

The API is the FastAPI application (apps/api/) that serves as the control plane. It handles all user-facing REST requests, persists state to PostgreSQL, starts Temporal workflows, and streams real-time Run Events via SSE.

Worker ​

The Worker (apps/worker/) is the Temporal worker process that executes Handler activities. It polls the Temporal task queue, runs step handlers against network devices, and reports results back to the API via internal HTTP endpoints.

Temporal ​

Temporal is the open-source workflow orchestration platform used by Hegemony. It provides durable, fault-tolerant workflow execution, automatic retries, and a state management layer that survives process restarts.

SSE (Server-Sent Events) ​

Server-Sent Events is the HTTP/1.1 push mechanism used to stream Run Events from the API to the React UI in real time. The endpoint is GET /runs/{id}/events.

BFF Tickets are used to authenticate SSE connections because browsers cannot attach Authorization headers in the EventSource API.

File Repository ​

A File Repository is Hegemony's managed shared file store, backed by S3-compatible object storage. File repositories support logical folder hierarchies and file operations (upload, import, move, rename, delete) for artifacts such as firmware images, scripts, and supporting assets.

Registry Credential ​

A Registry Credential is an organization's login for an external container registry (a host such as ghcr.io or docker.io, a username, and the password as a secret reference). Container steps in the organization pull images from that host with it automatically: the worker resolves the reference for the step and removes it when the step ends. One credential per host per organization; the value never enters the database.

Platform Registry ​

The Platform Registry is Hegemony's own container registry (zot on the S3 object store, started by the registry compose overlay). Container steps keep copies of the images they pull in it — their image cache, under orgs/<slug>/<upstream host>/… — and pull the copies on later runs; global/… holds platform-wide images. Steps reach it with short-lived tokens the worker mints per step; every request is authorized by the API through the registry proxy, and nobody logs in. See Container Registries.

Object Name ​

The human-facing name you give a flow, site, device, secret, secret backend, schedule, webhook, notification destination, repository, organization, API token or graph node. Every one of them follows the same rules:

  • Surrounding whitespace is stripped, and a name that is blank after stripping is rejected. Stripping is not cosmetic: flow versioning picks the next version by exact name match, so Nightly Backup and the same name with a trailing space would otherwise become two flows with separate version histories.
  • At most 128 characters.
  • No single word longer than 64 characters. Names appear in table cells, node boxes and page headers, none of which can break inside an unbroken run of characters, so one long pasted token would overflow whatever it lands in.
  • No control characters — line breaks and tabs break table rows, YAML export and log lines.

Names need not be unique, and they are not identifiers: variable names, run-variable names and organization slugs are separate, stricter things with their own patterns.

Names that predate these limits still load; they are rejected only when something tries to save them again.

The rules are enforced on the API's create and update requests, on bulk import through Configuration Exchange, and mirrored in the UI so a bad name is caught before the round trip. An import that carries a bad name fails with the offending section and entry named, rather than being silently corrected. References that address an entry by name are stripped the same way as the name itself — a site's parent path, for one — so stripping cannot leave a reference pointing at nothing.

Import checks the name rather than the bundle schema declaring it, because the bundle models serialize live rows on export too: a name written under the older, looser limit still has to come back out of the system that stored it.

  • Schema: apps/api/schemas.py (DisplayName, MAX_DISPLAY_NAME_LENGTH, MAX_DISPLAY_NAME_WORD_LENGTH)
  • UI: apps/ui/src/lib/validation.ts (validateDisplayName, LIMITS)

Configuration Exchange ​

Hegemony supports bulk Configuration Exchange of flow definitions, device inventory, and platform configuration as YAML or Git-backed bundles. This enables version-controlled backups, environment promotion, and sharing of flow libraries.

  • API: POST /config-exchange/operations · GET /config-exchange/schema · GET /config-exchange/projection

Git Integration ​

Git Repository ​

A registered external Git remote (HTTPS or SSH) that Hegemony can clone, fetch from, and push to. Credentials are stored as Secret References and resolved just-in-time.

  • Code: apps/api/models.py (GitRepository) · apps/api/routers/git_repositories.py
  • API: GET/POST/PATCH/DELETE /git-repositories · POST /git-repositories/{id}/test-connection

Sync Mode ​

Controls the direction of synchronisation between a linked flow and its Git path.

ValueBehaviour
syncedBidirectional — auto-push on commit, pull available
readonlyGit → Hegemony only — local edits blocked, pull-only
detachedLinkage preserved, no sync occurs
  • Code: packages/core/enums.py (SyncMode)

Pull Sync ​

Reading a flow definition and its attachments from Git into the Hegemony database draft. Detects dirty-draft conflicts when the local draft has uncommitted changes.

  • Code: apps/api/services/sync/flow_git/pull.py (sync_flow_from_git)
  • API: POST /flows/{id}/sync-from-git

Push Sync ​

Writing the current committed flow version to Git in exploded format, committing, and pushing. Detects stale-remote conditions.

  • Code: apps/api/services/sync/flow_git/push.py (push_flow_to_git)
  • API: POST /flows/{id}/push-to-git

Async Push ​

A background mechanism where push operations are enqueued as sync history rows with status=queued and processed by the API's dispatcher loop, so that committing a synced flow doesn't block on the Git push.

  • Code: apps/api/services/sync/flow_git/queue.py (run_dispatcher_loop)

Exploded Format ​

The on-disk directory layout used when storing flows in Git:

text
<path>/<flow_slug>/flow.yaml
<path>/<flow_slug>/attachments/<filename>

Human-readable, diff-friendly, and editable from any IDE.

  • Code: apps/api/services/sync/serialization/layouts/exploded.py

Git Linkage ​

The set of columns on flow_definitions (git_repo_id, git_path, git_branch, sync_mode, last_synced_sha, last_synced_at) and flow_attachments (git_repo_id, git_file_path, last_synced_sha, last_synced_at) that tie a flow to a Git repository path.

Sync History ​

An audit log of every pull or push operation. Each record tracks direction, status (queued / running / succeeded / failed), trigger source, commit SHA, timestamps, and error detail. Also serves as the queue substrate for async push.

  • Code: apps/api/models.py (GitSyncHistory)
  • API: GET /flows/{id}/git-sync-history · GET /git-repositories/{id}/sync-history

Stale Remote ​

A condition during push sync where the remote branch has advanced past the flow's last_synced_sha. Hegemony attempts a fast-forward; if it fails, the push is rejected and the user must pull first.

Dirty Draft ​

A condition during pull sync where the local flow draft contains uncommitted changes that would be overwritten by the incoming Git content. The user is prompted to commit or discard before the pull can proceed.


Acronym Quick-Reference ​

For detailed definitions of auth acronyms see architecture/auth.md — Glossary.

AcronymFull Form
ABACAttribute-Based Access Control
ADActive Directory
APIApplication Programming Interface
BFFBackend-for-Frontend
CI/CDContinuous Integration / Continuous Deployment
CLICommand-Line Interface
CORSCross-Origin Resource Sharing
gNMIgRPC Network Management Interface
IdPIdentity Provider
JWKSJSON Web Key Set
JWTJSON Web Token
KVKey-Value (OpenBao / Vault secrets engine)
LDAPLightweight Directory Access Protocol
NETCONFNetwork Configuration Protocol
OIDCOpenID Connect
PKCEProof Key for Code Exchange
RBACRole-Based Access Control
RS256RSA Signature with SHA-256
SAMLSecurity Assertion Markup Language
SPASingle-Page Application
SSEServer-Sent Events
SSHSecure Shell
SSOSingle Sign-On
TLSTransport Layer Security
TTLTime To Live
UUIDUniversally Unique Identifier
XSSCross-Site Scripting

Released as open source under the AGPL-3.0-or-later license. Development is sponsored by Rexonix s.r.o.. Contact — [email protected].