parseAppConfigSections function

AppFahSections parseAppConfigSections({
  1. Object? userDoc,
  2. Object? projectDoc,
  3. Object? projectRulesDoc,
  4. String userSource = '~/.fah/config.yaml',
  5. String projectSource = '.fah/config.yaml',
  6. String projectRulesSource = '.fah/rules.yaml',
  7. String? envMode,
})

Parses the already-loaded yaml documents into AppFahSections.

Every section parse is isolated: a malformed section records a warning naming its file + section and falls back to the default, never poisoning the other sections (AC7). Throws nothing.

Implementation

AppFahSections parseAppConfigSections({
  Object? userDoc,
  Object? projectDoc,
  Object? projectRulesDoc,
  String userSource = '~/.fah/config.yaml',
  String projectSource = '.fah/config.yaml',
  String projectRulesSource = '.fah/rules.yaml',
  String? envMode,
}) {
  final warnings = <String>[];
  final user = _coerceScopeDoc(userDoc, userSource, warnings);
  final project = _coerceScopeDoc(projectDoc, projectSource, warnings);
  final roles = _parseRolesSection(user, userSource, warnings);
  // tools: — both scopes parse independently; the caller stacks them
  // (global < project < runtime) in the live resolution.
  final userTools = _parseTools(user?['tools'], userSource, warnings);
  final projectTools = _parseTools(
    project?['tools'],
    projectSource,
    warnings,
  );
  final ttsr = _parseTtsrSection(
    user,
    userSource,
    projectRulesDoc,
    projectRulesSource,
    warnings,
  );
  final redact = _parseRedactSection(user, userSource, warnings);
  final providerTimeouts = _parseTimeoutsSection(user, userSource, warnings);
  final loadMode = _resolveLoadMode(envMode, user, userSource, warnings);
  // Inventory #2 interim: `mcp:` stays CLI-only on mobile — say so instead
  // of silently ignoring it.
  final mcpConfigured = user?['mcp'] != null;
  if (mcpConfigured) {
    warnings.add(
      'mcp section in $userSource is not consumed by the app yet '
      '(MCP servers connect through the CLI harness)',
    );
  }
  return AppFahSections(
    roles: roles,
    ttsr: ttsr,
    userTools: userTools,
    projectTools: projectTools,
    redact: redact,
    providerTimeouts: providerTimeouts,
    loadMode: loadMode,
    mcpConfigured: mcpConfigured,
    warnings: warnings,
    userDoc: userDoc,
  );
}