Skip to content

[Feature] Centralize config: env asserts, magic numbers, fetch timeouts, settings re-read #32

@chronoai-shining

Description

@chronoai-shining

Severity: Medium

Configuration is scattered across process.env[...] reads in every module, with magic numbers inline, no required-env assertions, and Settings stored in Mongo but never re-read after boot.

Problems

1. No required-env assertions at boot.

  • sisyphus-api/src/db.ts:6-7, runner/aevatar-client.ts:5-7, runner/session-manager.ts:21-22, ingest/chrono-graph-client.ts:5-6, workflows/ornn-client.ts:5, workflows/mainnet-client.ts:6-7, workflows/reference-resolver.ts:6-7, papers/storage-client.ts:5-6 — all use process.env["X"] ?? "http://localhost:NNNN" fallbacks. In a k8s pod, the localhost fallback hits the pod itself and produces opaque ECONNREFUSED instead of "config missing".
  • GRAPH_ID defaults to empty string. The URL ${CHRONO_GRAPH_URL}/api/graphs//nodes (note empty segment) gets fired against the upstream silently.

2. Magic numbers everywhere.

  • Timeout literals 5000 / 10000 / 15000 / 30000 / 120000 ms scattered across aevatar-client.ts, storage-client.ts, chrono-graph-client.ts, mainnet-client.ts, ornn-client.ts.
  • MAX_NODES = 50_000 (papers/controllers/CompileController.ts:61).
  • MAX_CONCURRENT = 3, COMPILE_TIMEOUT_MS = 300_000 (papers/compiler.ts:9-10).
  • MAX_CACHE_SIZE = 500 (schemas/validator.ts:8).
  • TTLs 365 * 24 * 60 * 60 (audit-event.ts:47) and 30 * 24 * 60 * 60 (event-log.ts:13).

3. Settings stored in Mongo but never re-read.

  • Settings.verifyCronIntervalHours (admin/models/settings.ts:11) is updatable via PUT /settings.
  • runner/session-manager.ts:24-27 reads process.env.VERIFY_CRON_INTERVAL_HOURS once at module load. Mongo updates have no effect until pod restart.
  • Same for eventRetentionDays (TTL set at index-creation time, never reapplied via collMod).

Remediation

Build a single sisyphus-api/src/config.ts:

function required(name: string): string {
  const v = process.env[name];
  if (!v) throw new Error(`Required env var ${name} not set`);
  return v;
}

export const config = Object.freeze({
  port: parseInt(process.env["PORT"] ?? "8080", 10),
  mongoUri: required("MONGO_URI"),
  dbName: process.env["DB_NAME"] ?? "sisyphus",
  graphId: required("GRAPH_ID"),  // explicit assert — not "" silently
  chronoGraph: { url: required("CHRONO_GRAPH_URL"), timeoutMs: 30_000 },
  chronoStorage: { url: required("CHRONO_STORAGE_URL"), bucket: required("STORAGE_BUCKET") },
  ornn: { url: required("CHRONO_ORNN_URL"), timeoutMs: 15_000 },
  aevatar: { url: required("AEVATAR_API_URL"), scopeId: required("SCOPE_ID") },
  papers: { maxNodes: 50_000, maxConcurrent: 3, compileTimeoutMs: 300_000 },
  schemas: { lruSize: 500 },
  retention: { eventDays: 30, auditDays: 365 },
  verifyCron: { intervalHours: 6 },  // initial; reload from Mongo on boot
});

Drop the process.env[...] reads in clients; import config.x.

For Mongo-backed settings, on boot read Settings.verifyCronIntervalHours and override config.verifyCron.intervalHours. Add a settings-changed hook (Mongo change stream or polled by version) that calls stopVerifyCron(); startVerifyCron();. For expireAfterSeconds on event_logs, log + reapply via collMod if drifted.

Strip trailing slashes from URLs in the config loader so callers don't have to.

Metadata

Metadata

Labels

dxDeveloper experienceenhancementNew feature or request

Type

No type
No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions