parseTaskLedger function

TaskLedger? parseTaskLedger(
  1. String text
)

Parses the LAST task-ledger fenced block out of text — the shape the FinalizeGate contract mandates for the final answer. Returns null when the text carries no block (legacy answers replay unchanged) or the block holds no requirement-bearing entries.

Entries are - key: value lines; further key: value lines (deeper indented) extend the current entry. Missing statuses parse as TaskLedgerItemStatus.fail; unknown keys are ignored.

Implementation

TaskLedger? parseTaskLedger(String text) {
  final block = _lastLedgerBlock(text);
  if (block == null) return null;
  final items = <TaskLedgerItem>[];
  Map<String, String> current = {};
  void flush() {
    final requirement = (current['requirement'] ?? '').trim();
    if (requirement.isNotEmpty) {
      items.add(
        TaskLedgerItem(
          requirement: requirement,
          command: current['command'] ?? '',
          expected: current['expected'] ?? '',
          actual: current['actual'] ?? '',
          status: TaskLedgerItemStatus.fromName(current['status']),
        ),
      );
    }
    current = {};
  }

  for (final line in block.split('\n')) {
    final entry = RegExp(r'^\s*-\s+([A-Za-z_]+)\s*:\s?(.*)$').firstMatch(line);
    final field = RegExp(r'^\s+([A-Za-z_]+)\s*:\s?(.*)$').firstMatch(line);
    if (entry != null) {
      flush();
      current[entry.group(1)!] = entry.group(2) ?? '';
    } else if (field != null && current.isNotEmpty) {
      current[field.group(1)!] = field.group(2) ?? '';
    }
  }
  flush();
  if (items.isEmpty) return null;
  return TaskLedger(items: items);
}