LearnNewsExamplesServices
Frontmatter
id12107
titleStage 5: retract Env.mjs consumer-facing exports + JSDoc anti-doctrine
stateClosed
labels
enhancementairefactoring
assigneesneo-opus-ada
createdAtMay 27, 2026, 10:14 PM
updatedAtMay 30, 2026, 6:55 AM
githubUrlhttps://github.com/neomjs/neo/issues/12107
authorneo-opus-ada
commentsCount0
parentIssue12101
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtMay 30, 2026, 6:55 AM

Stage 5: retract Env.mjs consumer-facing exports + JSDoc anti-doctrine

Closed v13.0.0/archive-v13-0-0-chunk-14 enhancementairefactoring
neo-opus-ada
neo-opus-ada commented on May 27, 2026, 10:14 PM

Authored by Claude Opus 4.7 (Claude Code 1M). Origin Session ID: ba55de70-c601-448e-9eb4-9c214be1d9c6. Sub of #12101 (parent Epic).

Context

Post-Stage-3/4 cleanup. By this stage, ZERO consumers of Env.parseX() from src/util/Env.mjs should remain (Stages 3 + 4 migrated them all to AiConfig.X.Y Proxy-routed reads). Stage 5 retracts the consumer-facing surface + deletes the regression-as-doctrine JSDoc.

The Problem

src/util/Env.mjs currently exports parseBool / parseNumber / parsePort / parseString / parseUrl / parseKeepAlive / applyEnvBindings as a public consumer API. JSDoc at lines 18-19 + line 128 institutionalizes the regression as canonical:

"The canonical 2-value chain is Env.parseX('NEO_X') ?? AiConfig.X — the env var name appears ONCE per consumer call site."

This documented pattern drove the accretion across multiple agent cycles per Epic #12101 Problem statement.

The Architectural Reality

Post-Stage-1: Env.parsers typed-parser registry lives inside BaseConfig's scope; parsers are internal. Stage 4 codemod migrated all consumer-side Env.parseX() calls to AiConfig.X.Y direct reads. By Stage 5, only BaseConfig itself uses Env.parseX internally.

The Fix

  • Retract parseBool / parseNumber / parsePort / parseString / parseUrl / parseKeepAlive consumer-facing exports — move to BaseConfig-internal scope (or keep as Env.parsers typed-parser registry per Stage 1 OQ5).
  • Delete applyEnvBindings default export (no remaining callers).
  • Delete consumer-pattern JSDoc anti-doctrine on lines 18-19, 128 — the Env.parseX('NEO_X') ?? AiConfig.X framing was the regression-as-doctrine.
  • Replace top-of-file JSDoc with new framing: "Internal parser registry for Neo.ai.BaseConfig; not consumer-facing. Consumers read AiConfig.X.Y via Provider-extending substrate."

Acceptance Criteria

  • parseBool / parseNumber / parsePort / parseString / parseUrl / parseKeepAlive consumer-facing exports retracted from src/util/Env.mjs.
  • applyEnvBindings default export deleted (verify zero remaining callers via grep "applyEnvBindings" ai test src --include="*.mjs").
  • Consumer-pattern JSDoc anti-doctrine (lines 18-19, 128 in current Env.mjs) deleted.
  • New top-of-file JSDoc reframes Env.mjs as BaseConfig-internal parser registry.
  • Test suite passes; runtime behavior unchanged (parsers still functional internal to BaseConfig).

Out of Scope

  • Legacy applyEnv() path deletion in BaseConfig.mjs (Stage 6 owns)
  • Parser-registry mechanism (Stage 1 decides location per OQ5)

Related

  • Parent Epic: #12101
  • Blocked by: Stage 3 + Stage 4 (all consumers migrated)
  • Discussion: #12100 Stage 5 v14

Handoff Retrieval Hints: query_raw_memories("Stage 5 Env.mjs retraction consumer-facing") + grep Env\.parse in ai test post-Stage-4-merge to verify zero consumers

tobiu referenced in commit fd7fb24 - "refactor(ai): Stage-5 — make Neo.util.Env BaseConfig-internal; retract consumer doctrine + applyEnvBindings (#12107) (#12189) on May 30, 2026, 6:55 AM
tobiu closed this issue on May 30, 2026, 6:55 AM