renderObligationsBlock function

String renderObligationsBlock(
  1. ObligationsLedger ledger, {
  2. int maxChars = obligationsBlockBudgetChars,
})

The block the projection appends at level 0 (issue #1380 A1): every open obligation is visible — or explicitly counted — after any hide/compact/flatten depth.

Layout: up to maxRenderedOpenEntries open lines (newest last), a counting tail when more are open, then closed entries oldest-last while the budget allows — the budget eats closed entries OLDEST first (E1) and never touches open lines. Every line's text is display-clipped (AC2 lives at the record level). Empty ledger renders as an empty string — no block.

Implementation

String renderObligationsBlock(
  ObligationsLedger ledger, {
  int maxChars = obligationsBlockBudgetChars,
}) {
  if (ledger.isEmpty) return '';
  const heading =
      'obligations ledger (engine-maintained; verbatim quotes with their '
      'source record — still owed unless marked done/superseded):';
  final open = ledger.open;
  final closed = [
    for (final e in ledger.entries)
      if (e.status != ObligationStatus.open) e,
  ];

  // Open entries: newest last, capped with an honest counting tail.
  final renderedOpen = open.length > maxRenderedOpenEntries
      ? open.sublist(open.length - maxRenderedOpenEntries)
      : open;
  final surplus = open.length - renderedOpen.length;

  // Closed entries trail oldest-last; the budget eats them from the top
  // (oldest first) once the open block plus heading no longer fit.
  final keptClosedNewestFirst = <ObligationEntry>[];
  var used =
      heading.length + 32; // envelope tags, separators, surplus-tail line
  if (surplus > 0) {
    used +=
        '\n… and $surplus more open obligations (read '
                'the ledger record for the full list)'
            .length;
  }
  for (final e in renderedOpen) {
    used += _obligationLine(e).length + 1;
  }
  for (final e in closed.reversed) {
    final cost = _obligationLine(e).length + 1;
    if (used + cost > maxChars) break;
    used += cost;
    keptClosedNewestFirst.add(e);
  }
  final keptClosed = keptClosedNewestFirst.reversed.toList();
  if (renderedOpen.isEmpty && keptClosed.isEmpty && surplus == 0) return '';
  return [
    '<system-notice>',
    heading,
    for (final e in renderedOpen) _obligationLine(e),
    if (surplus > 0)
      '… and $surplus more open obligations (read the ledger record for '
          'the full list)',
    for (final e in keptClosed) _obligationLine(e),
    '</system-notice>',
  ].join('\n');
}