Context
Operator observation 2026-05-10 (post-PR #11069 merge):
"many magic numbers, while we do have e.g. ai/config.template. worth an exploration ticket, but not as high as a prio compared to get to the point where we can test the orchestrator."
Empirical anchor: ai/config.template.mjs (top-level) is the established Tier 1 config substrate. It's already the canonical home for global AI/MCP infrastructure config (transport, debug flag, mcpHttpPort, etc.). M3.5 + M4 substrate work has accumulated hardcoded constants outside that substrate that should ideally route through it.
Priority: explicitly lower than orchestrator-testable readiness per operator framing. This ticket is open-lane exploration; pickup happens AFTER orchestrator validates end-to-end.
The Magic Numbers
Audited surfaces (non-exhaustive; pickup-time intake should expand):
ai/daemons/TaskDefinitions.mjs (lines 7-13):
DEFAULT_POLL_INTERVAL_MS = 3000
DEFAULT_SUMMARY_SWEEP_INTERVAL_MS = 600000
DEFAULT_KB_SYNC_INTERVAL_MS = 1800000
DEFAULT_BACKUP_INTERVAL_MS = 86400000
- (Future M4 coordinator additions: SANDMAN, DREAM, GOLDEN_PATH, GRAPH_MAINTENANCE, HEARTBEAT, WAKE_SUBSTRATE — each will likely add another constant)
buildScripts/ai/backup.mjs (lines 363-365):
K = 3 (newest-bundle keep count)
N_DAYS = 30 (rotation cap)
Likely surfaces TBD (pickup-time empirical sweep):
- Per-coordinator service constants (each future coordinator may inline its own contention thresholds, off-peak windows, etc.)
ai/scripts/bridge-daemon.mjs polling intervals
ai/daemons/SwarmHeartbeatService.mjs poll cadence (currently 5 * 60 * 1000 constant)
- HealthService thresholds, etc.
The Problem
Hardcoded constants in code files create:
- Operator config-friction — to tune retention or cadence, operator edits source files instead of a single config file
- No environment-overlay —
ai/config.template.mjs already supports per-deployment overlays via env vars; magic numbers in TaskDefinitions don't get that benefit
- Drift risk — same constant repeated across files (e.g., test fixtures hardcoding
86400000 instead of importing DEFAULT_BACKUP_INTERVAL_MS) accumulates
- MX friction — agents reading the codebase have to chase down constants across files instead of reading one config namespace
Architectural Reality
Established Tier-1 config: ai/config.template.mjs (loads at process boot; supports env-var override; mature substrate).
Established Tier-3 config: ai/mcp/server/<server>/config.template.mjs per-server (memory-core, knowledge-base, etc.).
Orchestrator config home: unclear today. The cleanest path is likely a Tier-2 config namespace under ai/config.template.mjs like:
orchestrator: {
pollIntervalMs : 3000,
summarySweepIntervalMs : 600000,
kbSyncIntervalMs : 1800000,
backupIntervalMs : 86400000,
sandmanIntervalMs : 86400000,
backupRetention: {
keepNewestK : 3,
rotationDays : 30
}
}
TaskDefinitions.mjs + per-coordinator services + backup.mjs read from aiConfig.data.orchestrator.* instead of inlined constants.
Open Questions for /ticket-intake at Pickup
- Naming convention:
aiConfig.data.orchestrator.* vs flat aiConfig.data.orchestratorPollIntervalMs? The Tier-1 config currently uses flat keys + nested objects mixed; sibling-pattern consultation needed.
- Migration unit: all-at-once (one PR migrates everything) OR per-coordinator-service (each new coordinator routes through config from inception, existing migrate later)? Pickup-time judgment.
- Test-fixture impact: specs hardcode
86400000 etc. for backup-interval default checks; migrating may require spec updates.
- Backup-cycle K + N_DAYS: these are buildScripts-territory (not orchestrator-territory); separate config namespace OR fold under orchestrator.backup?
Acceptance Criteria
Out of Scope
- Detailed prescription pre-staged here — would go stale per the empirical pattern (#11062/#11065 lesson). Pickup-time intake validates against post-orchestrator-validation reality.
- Other substrate magic numbers outside daemon/orchestrator scope (e.g., MCP server transport defaults, MailboxService TTLs, etc.) — sibling-fileable if surfaced.
- Operator-facing config docs — separate documentation pass after the migration lands.
Avoided Traps
- ❌ Migrate before orchestrator-validates — wrong sequencing per operator framing; would conflate magic-number cleanup with orchestrator-correctness validation
- ❌ Bundle with M4 coordinator extractions — separate scope; M4 coordinators ship with their own constants, then this ticket consolidates
- ❌ Pre-stage per-coordinator config keys — each coordinator file may evolve its own config needs; sweep-after pattern is cleaner
Provenance
- Operator observation 2026-05-10: "many magic numbers, while we do have e.g. ai/config.template. worth an exploration ticket, but not as high as a prio" — explicit lower-priority signal vs orchestrator-validation
- Empirical anchor: PR #11069 BackupCoordinatorService landing surfaced the constant pattern (DEFAULT_BACKUP_INTERVAL_MS hardcoded; K=3 + N_DAYS=30 retention constants in backup.mjs)
- Tier-1 config substrate:
ai/config.template.mjs (top-level, mature)
Related
- M3.5 keystone: #11022 (closed) + Sub-1/2/3/4 (#11041/#11044/#11051/#11068)
- M4 landscape (where additional constants will accumulate): #11062 (BackupCoord, MERGED via PR #11069), #11065 (SandmanCoord), #11070-#11074 (Dream/GoldenPath/GraphMaintenance/Heartbeat/WakeSubstrate Coords)
- Tier-3 sibling:
ai/mcp/server/memory-core/config.template.mjs
- Cleanup-companion (sibling-fileable): #10822 Config substrate cleanup epic
Self-Identification: @neo-opus-4-7 (Claude Opus 4.7, Claude Code) — exploration-priority filing per operator directive 2026-05-10. Open lane; pickup deferred until orchestrator-validation milestone clears.
Origin Session ID: c2912891-b459-4a03-b2af-154d5e264df1
Context
Operator observation 2026-05-10 (post-PR #11069 merge):
Empirical anchor:
ai/config.template.mjs(top-level) is the established Tier 1 config substrate. It's already the canonical home for global AI/MCP infrastructure config (transport, debug flag, mcpHttpPort, etc.). M3.5 + M4 substrate work has accumulated hardcoded constants outside that substrate that should ideally route through it.Priority: explicitly lower than orchestrator-testable readiness per operator framing. This ticket is open-lane exploration; pickup happens AFTER orchestrator validates end-to-end.
The Magic Numbers
Audited surfaces (non-exhaustive; pickup-time intake should expand):
ai/daemons/TaskDefinitions.mjs(lines 7-13):DEFAULT_POLL_INTERVAL_MS = 3000DEFAULT_SUMMARY_SWEEP_INTERVAL_MS = 600000DEFAULT_KB_SYNC_INTERVAL_MS = 1800000DEFAULT_BACKUP_INTERVAL_MS = 86400000buildScripts/ai/backup.mjs(lines 363-365):K = 3(newest-bundle keep count)N_DAYS = 30(rotation cap)Likely surfaces TBD (pickup-time empirical sweep):
ai/scripts/bridge-daemon.mjspolling intervalsai/daemons/SwarmHeartbeatService.mjspoll cadence (currently5 * 60 * 1000constant)The Problem
Hardcoded constants in code files create:
ai/config.template.mjsalready supports per-deployment overlays via env vars; magic numbers in TaskDefinitions don't get that benefit86400000instead of importingDEFAULT_BACKUP_INTERVAL_MS) accumulatesArchitectural Reality
Established Tier-1 config:
ai/config.template.mjs(loads at process boot; supports env-var override; mature substrate).Established Tier-3 config:
ai/mcp/server/<server>/config.template.mjsper-server (memory-core, knowledge-base, etc.).Orchestrator config home: unclear today. The cleanest path is likely a Tier-2 config namespace under
ai/config.template.mjslike:orchestrator: { pollIntervalMs : 3000, summarySweepIntervalMs : 600000, kbSyncIntervalMs : 1800000, backupIntervalMs : 86400000, sandmanIntervalMs : 86400000, // ... per future M4 coordinator backupRetention: { keepNewestK : 3, rotationDays : 30 } }TaskDefinitions.mjs+ per-coordinator services + backup.mjs read fromaiConfig.data.orchestrator.*instead of inlined constants.Open Questions for /ticket-intake at Pickup
aiConfig.data.orchestrator.*vs flataiConfig.data.orchestratorPollIntervalMs? The Tier-1 config currently uses flat keys + nested objects mixed; sibling-pattern consultation needed.86400000etc. for backup-interval default checks; migrating may require spec updates.Acceptance Criteria
/ticket-intakevalidates premise post-orchestrator-validation milestoneai/config.template.mjsadds orchestrator config namespace (shape TBD per Open Question 1)ai/daemons/TaskDefinitions.mjsreads constants from config instead of inliningbuildScripts/ai/backup.mjsretention K + N_DAYS read from configDEFAULT_*constants)86400000etc. with config references where appropriate)pull-request §6.1Out of Scope
Avoided Traps
Provenance
ai/config.template.mjs(top-level, mature)Related
ai/mcp/server/memory-core/config.template.mjsSelf-Identification: @neo-opus-4-7 (Claude Opus 4.7, Claude Code) — exploration-priority filing per operator directive 2026-05-10. Open lane; pickup deferred until orchestrator-validation milestone clears.
Origin Session ID: c2912891-b459-4a03-b2af-154d5e264df1