deploy/app.env
Rama main · réplica de lectura del repositorio original.
# shellcheck shell=bash
# ════════════════════════════════════════════════════════════════════════════
# app.env — SynaptoMind service configuration
#
# Vendored from bun-templates/deploy (see lib/common.sh and install.sh).
# Provenance: https://forgejo.home.lan/authelia/bun-templates commit 89be318daf8adab5ddca957162b3b7df8429e725
# ════════════════════════════════════════════════════════════════════════════
# ── Identity ───────────────────────────────────────────────────────────────
APP_NAME="synaptomind"
APP_DESC="SynaptoMind — thought-graph engine"
# ── Distribution ───────────────────────────────────────────────────────────
# "binary" installs the published release tarball (see
# synaptomind/adr/2026-10-01-unify-deploy-framework-adr.md): no bun,
# no node_modules, no git checkout on the host. Flip to "source" for a
# developer install from a git checkout.
DIST="binary"
# ── binary mode ────────────────────────────────────────────────────────────
# Asset URL = ${RELEASES_BASE}/${TAG}/${ASSET_PATTERN}
RELEASES_BASE="https://github.com/zumik3-del/synaptomind/releases/download"
# The LIST endpoint, not /releases/latest: /latest silently excludes prereleases
# and cannot express CHECKOUT_POLICY. Unauthenticated = 60 requests/hour per IP,
# so a 403/429 surfaces as an explicit error naming the --version <tag> remedy.
RELEASE_API="https://api.github.com/repos/zumik3-del/synaptomind/releases?per_page=30"
# SINGLE QUOTES ARE REQUIRED: load_app_env() sources this file, so double quotes
# would expand ${APP_NAME}/${TAG}/${OS}/${ARCH} here and leave render_template()
# nothing to substitute. Same for APP_VERSION_CMD, whose ${BIN} is set by
# app_version() at call time.
ASSET_PATTERN='${APP_NAME}-${TAG}-${OS}-${ARCH}.tar.gz'
APP_VERSION_CMD='${BIN} --version'
# ── source mode (retained for developer installs) ──────────────────────────
# REPO_URL stays REQUIRED even in binary mode: the frozen updater.sh bootstrap
# shallow-clones the chosen tag to stage that release's own deploy/update.sh.
REPO_URL="https://github.com/zumik3-del/synaptomind.git"
# stable | latest | prerelease select a release tag. A <branch> value is
# rejected in binary mode — a branch has no release asset.
CHECKOUT_POLICY="stable"
# ── Paths ──────────────────────────────────────────────────────────────────
INSTALL_DIR="/opt/synaptomind"
DATA_DIR="/var/lib/synaptomind"
RUN_DIR=""
# R1 (ADR addendum #1122): the app's own config home is DATA_DIR. The resolver is
# cwd-relative and has no flag (src/config.ts:267 loadFileConfig() ->
# join(process.cwd(), 'config.json')) and the unit's WorkingDirectory is fixed at
# /opt/synaptomind, so the two are bridged by CONFIG_LINK_NAME below: the config
# LIVES in /var/lib/synaptomind and is REACHED through the link. CONFIG_FILE
# itself is documentation and assertion material — no framework code reads it.
# It exists so "where does synaptomind's config live?" has ONE answer per class of
# file: settings here, operator/secret env in /etc (R2), deploy state in RUN_DIR.
CONFIG_FILE="/var/lib/synaptomind/config.json"
# The link itself, created/refreshed by the installer AFTER seeding. On the live
# host this link already exists (hand-made), so an install reports it preserved.
CONFIG_LINK_NAME="config.json"
# ── First-run seeding ──────────────────────────────────────────────────────
# config.json is NOT in SEED_FILES any more: the payload tree is swapped on every
# binary update, so a config seeded there competes with the operator's own file
# for one pathname. It is seeded into DATA_DIR and reached through the link above.
SEED_FILES=".env.example:.env"
SEED_FILES_DATA="config.json.example:config.json"
GENERATE_SECRET_IN=".env"
# ── Runtime / service ──────────────────────────────────────────────────────
# Explicit, not empty. An empty SERVICE_USER makes resolve_target_user()
# (lib/common.sh:162) fall through to SUDO_USER and then `id -un`, so the same
# installer run renders User=root when invoked as root without SUDO_USER, and
# the service silently runs as root. Naming the user removes the dependence on
# who ran the installer (ADR addendum #1122 R4). TARGET_GROUP defaults to this
# value, so the rendered unit also gains Group=opencode.
SERVICE_USER="opencode"
EXEC_START=""
PORT="3105"
# Optional. Port written to mcp.httpPort when a FRESH config.json is seeded; empty
# means "PORT + 1" (resolve_mcp_port in lib/common.sh). An existing config.json is
# never rewritten, so this affects new installs only — it exists to break the +1
# when 3106 is already taken on the host. Must differ from PORT.
MCP_PORT=""
HEALTH_URL=""
HEALTH_TIMEOUT="60"
# A SECOND health window, used only when HEALTH_TIMEOUT expired with no answer at
# all. A timeout is this run's own bound, not a fact about the service, so an
# update that cannot confirm the new version is reported UNVERIFIED instead of
# failed-with-a-rollback (which stops the unit and restores the database). Raise
# this on a host with a slow start. 0 disables the re-check — not recommended.
HEALTH_CONFIRM_TIMEOUT="30"
# ── host requirements ──────────────────────────────────────────────────────
# "no" — a binary host needs no bun at install time or at runtime; the embedder
# is the same executable spawned as `synaptomind --embedder`.
REQUIRES_BUN="no"
# "git tar" — tar extracts the release payload, git is only the updater.sh
# bootstrap (it clones the tag to stage that release's update.sh).
SYSTEM_DEP_CMDS="git tar"
HOOKS_DIR=""
LIB_RAW_URL="https://raw.githubusercontent.com/zumik3-del/synaptomind/main/deploy/lib/common.sh"