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.
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 useprocess.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_IDdefaults to empty string. The URL${CHRONO_GRAPH_URL}/api/graphs//nodes(note empty segment) gets fired against the upstream silently.2. Magic numbers everywhere.
5000/10000/15000/30000/120000ms scattered acrossaevatar-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).365 * 24 * 60 * 60(audit-event.ts:47) and30 * 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 viaPUT /settings.runner/session-manager.ts:24-27readsprocess.env.VERIFY_CRON_INTERVAL_HOURSonce at module load. Mongo updates have no effect until pod restart.eventRetentionDays(TTL set at index-creation time, never reapplied viacollMod).Remediation
Build a single
sisyphus-api/src/config.ts:Drop the
process.env[...]reads in clients; importconfig.x.For Mongo-backed settings, on boot read
Settings.verifyCronIntervalHoursand overrideconfig.verifyCron.intervalHours. Add a settings-changed hook (Mongo change stream or polled by version) that callsstopVerifyCron(); startVerifyCron();. ForexpireAfterSecondsonevent_logs, log + reapply viacollModif drifted.Strip trailing slashes from URLs in the config loader so callers don't have to.