LearnNewsExamplesServices
Frontmatter
id14957
titleRoute orchestrator data paths through AiConfig use-site reads
stateClosed
labels
enhancementairefactoringtestingarchitecture
assigneesneo-gpt, neo-fable
createdAt1:50 PM
updatedAt2:58 PM
githubUrlhttps://github.com/neomjs/neo/issues/14957
authorneo-gpt
commentsCount0
parentIssue12456
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAt2:58 PM

Route orchestrator data paths through AiConfig use-site reads

Closed Backlog/active-chunk-5 enhancementairefactoringtestingarchitecture
neo-gpt
neo-gpt commented on 1:50 PM

Context

PR #14941 is the second bounded cleanup batch under parent epic #12456. It introduces owning orchestrator.dataDir and orchestrator.dbPath leaves and removes duplicated environment/default derivations from the orchestrator daemon path.

A prior #12456 census correctly classified the daemon path as a pre-bootstrap exception because no owning leaf existed then. This ticket changes that premise deliberately: once the leaves exist, all post-bootstrap consumers must obey ADR 0019’s direct use-site-read contract. The current PR’s Config Template SSOT lint falsifies the first implementation shape because taskDefinitions.mjs captures and re-exports the resolved leaves at module scope.

This leaf exists so the one-PR batch has a native, non-epic close target. Live latest-open, local archive, and recent A2A claim sweeps immediately before creation found no equivalent ticket.

The Problem

The current orchestrator paths are re-derived from environment variables and literals in more than one module. Moving those derivations into AiConfig is correct, but replacing them with:

export const DEFAULT_DB_PATH = AiConfig.orchestrator.dbPath;
export const DEFAULT_DATA_DIR = AiConfig.orchestrator.dataDir;

would preserve ADR 0019 §3 B1 and freeze reactive provider values at import time. It also makes a non-entrypoint helper import Neo/AiConfig merely to export config primitives. Hosted CI catches both exported config values and module-scope primitive leaf capture.

The Architectural Reality

  • ai/config.template.mjs owns Agent OS deployment leaves and environment bindings.
  • ai/daemons/orchestrator/daemon.mjs is an entrypoint; it may import AiConfig and read resolved leaves after the config-freshness guard.
  • ai/daemons/orchestrator/taskDefinitions.mjs is a non-entrypoint helper and the existing B1/C1 precedent named by ADR 0019.
  • Runtime services that consume data/database paths must read the owning leaf at the use site. A pure defaults module is allowed only for a genuine pre-bootstrap boundary and must contain literals/env names with no Neo import.
  • PID/log path construction must stay lazy enough that stale overlays reach assertConfigFresh instead of crashing before the actionable guard.

The structure-map gate confirms these are existing owners under ai/daemons/orchestrator/ and ai/daemons/orchestrator/services/. No new service or file placement is required by default.

The Fix

  1. Add root orchestrator.dataDir and orchestrator.dbPath leaves with the current literal defaults and environment names.
  2. Remove duplicate raw environment/default derivations.
  3. Remove module-scope AiConfig leaf captures and config-value re-exports from taskDefinitions.mjs.
  4. Migrate consumers to direct use-site reads, without value threading or hidden fallbacks.
  5. Keep daemon PID/log path reads post-freshness-guard and fail loud on a missing leaf.
  6. Add regressions proving provider refresh/override behavior reaches consumers and that the standalone daemon still boots through the intended guard path.

Contract Ledger

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
AiConfig.orchestrator.dataDir ADR 0019 + root config template Owning leaf for daemon/runtime data path Existing literal default via leaf only Leaf JSDoc env-binding + daemon boot specs
AiConfig.orchestrator.dbPath ADR 0019 + root config template Owning leaf for graph DB path Existing literal default via leaf only Leaf JSDoc env-binding + consumer specs
Orchestrator consumers ADR 0019 §3 B1 / §5 Direct resolved reads at use sites No defensive fallback Existing class/method JSDoc freshness/override regressions
PID/log boot path Config freshness guard Resolve after freshness assertion Actionable migrate-config failure Daemon JSDoc stale-overlay/boot probe

Decision Record impact

Aligned with ADR 0019. The ticket applies its A1/B1/C1 rules and does not amend the ADR.

Acceptance Criteria

  • Root AiConfig declares the two orchestrator leaves with the existing defaults and env bindings.
  • No touched orchestrator module re-derives these values from process.env.
  • No DEFAULT_DB_PATH / DEFAULT_DATA_DIR export captures an AiConfig leaf at module scope.
  • Post-bootstrap consumers read resolved leaves at the use site without pass-along or hidden defaults.
  • Any retained pre-bootstrap defaults boundary is pure, Neo-free, and justified by an actual pre-bootstrap consumer.
  • Stale overlays still fail through the actionable config-freshness guard before path use.
  • Focused orchestrator/service/config specs cover defaults, env overrides, provider freshness, and real daemon boot.
  • ADR-0019 config SSOT lint and exact-head hosted CI pass.
  • The closing PR uses Resolves #N for this leaf.

Out of Scope

  • Broad cleanup of unrelated task-definition fields or scheduler behavior.
  • Changing the literal path defaults or environment variable names.
  • Introducing a generic config pass-along object.
  • Splitting leaf declarations and consumer migration into separate PRs.

Avoided Traps

  • Treating “env derivation removed” as sufficient while retaining B1 exports.
  • Eager module-load path construction before config freshness is checked.
  • Coupling a genuine pre-bootstrap wrapper to Neo merely to read AiConfig.
  • Leaving the parent epic as the PR close target.

Related

  • Parent epic: #12456
  • Implementation PR: #14941
  • Adjacent batches: #14935, #14942, and leaf #14956
  • Mechanical lint lane: #14500
  • Authority: learn/agentos/decisions/0019-aiconfig-reactive-provider-ssot.md

Origin Session ID: de713f27-0e82-4960-b4c6-f281e0c36449

Handoff Retrieval Hints

  • Memory Core: ADR 0019 taskDefinitions DEFAULT_DB_PATH DEFAULT_DATA_DIR module-scope capture
  • Exact implementation anchor: PR #14941 at dd6211c45370223b4c58984932ee40006ab4a21e
tobiu referenced in commit d055012 - "refactor(orchestrator): ADR-0019 batch-2 — dbPath/dataDir provider leaves replace module-level env derivation (#12456) (#14941) on 2:58 PM
tobiu closed this issue on 2:58 PM