LearnNewsExamplesServices
Frontmatter
id12648
titleRename PascalCase loose-fn helper files to camelCase
stateClosed
labels
enhancementairefactoringarchitecture
assigneesneo-opus-ada
createdAtJun 6, 2026, 7:59 PM
updatedAtJun 6, 2026, 10:51 PM
githubUrlhttps://github.com/neomjs/neo/issues/12648
authorneo-opus-ada
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtJun 6, 2026, 10:51 PM

Rename PascalCase loose-fn helper files to camelCase

Closed v13.0.0/archive-v13-0-0-chunk-16 enhancementairefactoringarchitecture
neo-opus-ada
neo-opus-ada commented on Jun 6, 2026, 7:59 PM

Context

Operator-flagged during the #12123 / PR #12642 REM-retention work: ai/services/memory-core/helpers/RemRunStateStore.mjs carries a PascalCase filename, but it is a loose-function-export helper (no class). The Neo naming convention reserves PascalCase filenames for classes (including neo classes — extends core.Base, static config). Loose-function-export helpers, namespace-object modules, and constants modules should use camelCase filenames.

The trigger generalizes: a systematic sweep shows the pattern fails across the ai/ tree (concentrated in helpers/ dirs) and once in buildScripts/.

The Problem

A PascalCase filename falsely signals "this is a class" to both human readers and agents enumerating the tree. The cost compounds: a reader opening ConsumerFrictionHelper.mjs or RemRunStateStore.mjs expects a class with static config + instance methods, then finds a flat list of export functions. The convention exists precisely to make PascalCase ⇒ class a reliable at-a-glance signal.

V-B-A evidence (find ai -name '[A-Z]*.mjs' | xargs grep -L '^…class [A-Z]'):

  • 156 PascalCase .mjs in ai/; 17 have no class declaration.
  • Each confirmed loose-fn / namespace-object / constants module via grep '^export' (e.g. RemRunStateStore.mjs → 0 class declarations, 7 export function).

The Architectural Reality

PascalCase.mjs ⇒ a class file (class X extends Base + Neo.setupClass(X), or a plain export default class). camelCase ⇒ a module of loose exports. The files below all fail the class test. Renaming each requires a repo-wide inbound-import sweep (every import … from '.../RemRunStateStore.mjs' site updated): scoped greps miss .mjs @see / string refs, and synced apps/portal/resources/data + frozen resources/content must be excluded; verify grep for each old basename returns 0.

The Fix

Rename each to camelCase + update all import sites.

ai/ — loose-function helpers (12):

  • services/memory-core/helpers/RemRunStateStore.mjsremRunStateStore.mjs
  • services/memory-core/helpers/ConsumerFrictionHelper.mjsconsumerFrictionHelper.mjs
  • services/memory-core/helpers/HarnessClassifier.mjsharnessClassifier.mjs
  • services/memory-core/helpers/EmbeddingProviderConfig.mjsembeddingProviderConfig.mjs
  • services/graph/ProviderReadinessHelper.mjsproviderReadinessHelper.mjs
  • services/knowledge-base/helpers/KbReconciliationEngine.mjskbReconciliationEngine.mjs
  • services/knowledge-base/helpers/KbGarbageCollectionEngine.mjskbGarbageCollectionEngine.mjs
  • services/knowledge-base/helpers/TenantRepoAccessContract.mjstenantRepoAccessContract.mjs
  • services/knowledge-base/helpers/GitMirror.mjsgitMirror.mjs
  • mcp/server/shared/Logger.mjslogger.mjs
  • mcp/server/shared/helpers/DeploymentConfig.mjsdeploymentConfig.mjs
  • mcp/validation/OpenApiValidator.mjsopenApiValidator.mjs (loose functions + an export {} block)

ai/ — constants / namespace-object / re-export modules (5):

  • daemons/orchestrator/TaskDefinitions.mjstaskDefinitions.mjs (constants + builders)
  • graph/queries/Traversal.mjstraversal.mjs (arrow-fn exports)
  • services/knowledge-base/helpers/KbAlertRuleEngine.mjskbAlertRuleEngine.mjs (constants + rule fns)
  • services/knowledge-base/helpers/TenantRepoIngestEnvelopeBuilder.mjstenantRepoIngestEnvelopeBuilder.mjs (⚠ also rename the const TenantRepoIngestEnvelopeBuilder = {…} default-export identifier — a PascalCase const-object is the same misleading "class-like" signal)
  • mcp/server/memory-core/helpers/EmbeddingProviderConfig.mjsembeddingProviderConfig.mjs (re-export — follows the services-layer rename in lockstep)

buildScripts/ (1):

  • util/Sanitizer.mjssanitizer.mjs

Avoided Traps

  • Do NOT rename actual class files. PascalCase is correct for class X extends Base files (DreamService.mjs, SessionService.mjs, SemanticGraphExtractor.mjs, all of src/). The grep filter excludes them by construction.
  • Namespace-object default exports: for TenantRepoIngestEnvelopeBuilder.mjs, rename both the filename AND the identifier.
  • Re-exports follow the source: the MC EmbeddingProviderConfig.mjs only re-exports the services one — rename in lockstep, single PR.
  • Case-insensitive-FS hazard: on macOS, a pure case-change rename may need the two-step git mv X tmp && git mv tmp x to register.

Decision Record impact

None — aligned with the existing Neo naming convention (PascalCase ⇒ class). No ADR introduced or challenged.

Acceptance Criteria

  • All 18 files renamed to camelCase (filename + any PascalCase default-export identifier).
  • Every inbound import / @see / dynamic-import reference updated; grep for each old basename returns 0 outside excluded synced/frozen dirs.
  • Green CI (unit + lint) — no ERR_MODULE_NOT_FOUND.
  • Per-file judgment confirmed for the 5 constants/namespace cases (none is actually a class).

Out of Scope

  • src/ framework class files (PascalCase correct — they ARE classes).
  • Any file containing a class declaration.
  • A test/ sweep — this analysis covered ai/ + buildScripts/; a test/ pass is a reasonable follow-up if it surfaces instances.

Related

  • Triggered by #12123 / PR #12642 (RemRunStateStore retention work).

Origin Session ID: 5f3fd8c4-ce8d-4a69-bbfe-336c5eeffdd3 Retrieval Hint: "PascalCase loose-fn helper camelCase rename" / find ai -name '[A-Z]*.mjs' | xargs grep -L class Live latest-open sweep: checked latest 12 open issues + searched naming/convention/camelCase at 2026-06-06; no equivalent found.

tobiu referenced in commit 874830b - "refactor(ai): rename PascalCase loose-fn helper files to camelCase (#12648) (#12649) on Jun 6, 2026, 10:51 PM
tobiu closed this issue on Jun 6, 2026, 10:51 PM