Context
Operator-flagged 2026-05-25 during TaskDefinitions.mjs technical-debt exploration: "some vars feel not needed like DREAM_TASK_NAME => why should someone want to rename it." Companion to #11075 (MLX values → AiConfig migration) but a distinct concern shape — this is over-abstraction, not misplacement.
The Problem
ai/daemons/orchestrator/TaskDefinitions.mjs lines 7-11 export 5 task-name string constants:
export const PRIMARY_DEV_SYNC_TASK_NAME = 'primary-dev-sync';
export const TENANT_REPO_SYNC_TASK_NAME = 'tenant-repo-sync';
export const DREAM_TASK_NAME = 'dream';
export const GOLDEN_PATH_TASK_NAME = 'golden-path';
export const SWARM_HEARTBEAT_TASK_NAME = 'swarm-heartbeat';
The string values are stable cross-substrate identifiers — the same literals serve as:
- Property keys on the
tasks registry in buildTaskDefinitions()
- PID file basenames (
dream.pid, tenant-repo-sync.pid, …)
- Task-state DB keys consumed by
TaskStateService
- Health-payload field names emitted by
HealthService
- Log-line substrings
- Test fixture keys
- Doc references in
learn/agentos/
Renaming any literal would cascade across all these non-import surfaces — so the import-side constant insures nothing. It's a layer of indirection without an underlying refactor-safety guarantee.
Operator framing: "feel not needed... why should someone want to rename it." — the answer is: no one would rename 'dream' because the rename would break too many surfaces the constant doesn't cover.
The Fix
Single concrete prescription: inline the 5 string literals at every usage site and remove the 5 export declarations.
Surface audit (grep _TASK_NAME across ai/, test/, learn/):
ai/daemons/orchestrator/TaskDefinitions.mjs — 5 export decls + 5 computed property keys
ai/daemons/orchestrator/Orchestrator.mjs — 5 imports + ~10 uses in runIfDue(...) calls and state lookups
ai/daemons/orchestrator/scheduling/{primaryDevSync,tenantRepoSync,dream,goldenPath,swarmHeartbeat}.mjs — 1 import + 2-3 uses per file
ai/daemons/orchestrator/services/PrimaryRepoSyncService.mjs — 1 import + 1 use (default param)
ai/daemons/orchestrator/services/TenantRepoSyncService.mjs — 1 import + 1 use (default param)
ai/daemons/orchestrator/services/MaintenanceBackpressureService.mjs — 4 imports + uses including dependency arrays
test/playwright/unit/ai/daemons/orchestrator/scheduling/*.spec.mjs — imports + uses for state-keying assertions
Replacement shape:
import {DREAM_TASK_NAME} from '../TaskDefinitions.mjs';
this.cadenceEngine.runIfDue(DREAM_TASK_NAME, () => {...});
this.cadenceEngine.runIfDue('dream', () => {...});
Computed-property-key usages inside buildTaskDefinitions collapse from [DREAM_TASK_NAME]: {...} to dream: {...} (or kept as 'dream': {...} if hyphenation forces quoting).
Acceptance Criteria
Out of Scope
- MLX config values — covered by sibling #11075 (different concern shape: misplacement, not over-abstraction)
- Other ALL_CAPS constants in TaskDefinitions.mjs (
DEFAULT_DB_PATH, DEFAULT_DATA_DIR, DEFAULT_SCRIPT_DIR) — these are env-var-overridable path resolvers, semantically distinct from task-name labels
- Renaming the task-name string values themselves — operator framing was "why would someone want to rename" the literal; this ticket retires the indirection, NOT the underlying names
Avoided Traps
- ❌ Argue for keeping constants as a registry — the
buildTaskDefinitions().tasks object already serves as the canonical registry; the constants duplicate that discoverability without adding it
- ❌ Replace with an enum object (e.g.,
TASK_NAMES.DREAM) — that's the same indirection in a different shape; doesn't change the cost/benefit
- ❌ Bundle with #11075 MLX migration — distinct concern (over-abstraction vs misplacement), separate ticket per
feedback_ticket_prescription_clarity
- ❌ Retire
DEFAULT_* path resolvers in the same PR — those have legitimate env-var-coercion semantics, different shape
Provenance
- Operator observation 2026-05-25: "some vars feel not needed like DREAM_TASK_NAME => why should someone want to rename it. other items are REAL configuration values that belong into ai/config.template.mjs (and for that there should be a ticket already)" — first half = this ticket, second half = #11075
- Empirical anchor: TaskDefinitions.mjs at
7952a645e (current dev tip — though task-name lines unchanged since cloud-deployment service-task additions)
- Sibling-distinction reference: #11075 status-update comment 2026-05-25 explicitly separates these concerns
Related
- Sibling: #11075 (MLX config migration — distinct concern shape)
- Substrate-evolution context: cloud-deployment milestone (#11790 / #11791 / #11942 substrate landed; task-name surfaces are now stable enough that the constants' rename-safety argument is moot)
Self-Identification: @neo-opus-4-7 (Claude Opus 4.7, Claude Code) — substrate-evolution filing per operator-direction 2026-05-25 during TaskDefinitions.mjs technical-debt exploration. Open lane for pickup.
Authored by [Claude Opus 4.7] (Claude Code).
Context
Operator-flagged 2026-05-25 during TaskDefinitions.mjs technical-debt exploration: "some vars feel not needed like DREAM_TASK_NAME => why should someone want to rename it." Companion to #11075 (MLX values → AiConfig migration) but a distinct concern shape — this is over-abstraction, not misplacement.
The Problem
ai/daemons/orchestrator/TaskDefinitions.mjslines 7-11 export 5 task-name string constants:export const PRIMARY_DEV_SYNC_TASK_NAME = 'primary-dev-sync'; export const TENANT_REPO_SYNC_TASK_NAME = 'tenant-repo-sync'; export const DREAM_TASK_NAME = 'dream'; export const GOLDEN_PATH_TASK_NAME = 'golden-path'; export const SWARM_HEARTBEAT_TASK_NAME = 'swarm-heartbeat';The string values are stable cross-substrate identifiers — the same literals serve as:
tasksregistry inbuildTaskDefinitions()dream.pid,tenant-repo-sync.pid, …)TaskStateServiceHealthServicelearn/agentos/Renaming any literal would cascade across all these non-import surfaces — so the import-side constant insures nothing. It's a layer of indirection without an underlying refactor-safety guarantee.
Operator framing: "feel not needed... why should someone want to rename it." — the answer is: no one would rename
'dream'because the rename would break too many surfaces the constant doesn't cover.The Fix
Single concrete prescription: inline the 5 string literals at every usage site and remove the 5 export declarations.
Surface audit (grep
_TASK_NAMEacrossai/,test/,learn/):ai/daemons/orchestrator/TaskDefinitions.mjs— 5 export decls + 5 computed property keysai/daemons/orchestrator/Orchestrator.mjs— 5 imports + ~10 uses inrunIfDue(...)calls and state lookupsai/daemons/orchestrator/scheduling/{primaryDevSync,tenantRepoSync,dream,goldenPath,swarmHeartbeat}.mjs— 1 import + 2-3 uses per fileai/daemons/orchestrator/services/PrimaryRepoSyncService.mjs— 1 import + 1 use (default param)ai/daemons/orchestrator/services/TenantRepoSyncService.mjs— 1 import + 1 use (default param)ai/daemons/orchestrator/services/MaintenanceBackpressureService.mjs— 4 imports + uses including dependency arraystest/playwright/unit/ai/daemons/orchestrator/scheduling/*.spec.mjs— imports + uses for state-keying assertionsReplacement shape:
// Before import {DREAM_TASK_NAME} from '../TaskDefinitions.mjs'; this.cadenceEngine.runIfDue(DREAM_TASK_NAME, () => {...}); // After this.cadenceEngine.runIfDue('dream', () => {...});Computed-property-key usages inside
buildTaskDefinitionscollapse from[DREAM_TASK_NAME]: {...}todream: {...}(or kept as'dream': {...}if hyphenation forces quoting).Acceptance Criteria
ai/daemons/orchestrator/TaskDefinitions.mjs_TASK_NAMEimports + uses acrossai/andtest/inlined to string literalsMaintenanceBackpressureService.mjsdependency arrays use string literals directly{[CONSTANT]: {...}}) updated to literal keysgrep -rn "_TASK_NAME" ai/ test/returns zero hits post-mergepull-request §6.1Out of Scope
DEFAULT_DB_PATH,DEFAULT_DATA_DIR,DEFAULT_SCRIPT_DIR) — these are env-var-overridable path resolvers, semantically distinct from task-name labelsAvoided Traps
buildTaskDefinitions().tasksobject already serves as the canonical registry; the constants duplicate that discoverability without adding itTASK_NAMES.DREAM) — that's the same indirection in a different shape; doesn't change the cost/benefitfeedback_ticket_prescription_clarityDEFAULT_*path resolvers in the same PR — those have legitimate env-var-coercion semantics, different shapeProvenance
7952a645e(current dev tip — though task-name lines unchanged since cloud-deployment service-task additions)Related
Self-Identification: @neo-opus-4-7 (Claude Opus 4.7, Claude Code) — substrate-evolution filing per operator-direction 2026-05-25 during TaskDefinitions.mjs technical-debt exploration. Open lane for pickup.
Authored by [Claude Opus 4.7] (Claude Code).