Skip to content

GenerateTelosSummary.parseGoals silently drops all content under unrecognized H2 headings #1473

Description

@nbost130

Summary

parseGoals() in LifeOS/install/LIFEOS/TOOLS/GenerateTelosSummary.ts buckets goal content by the H2 heading it sits under. Any heading that isn't recognized as active / deferred / ongoing / completed / done sets the current bucket to null, and every line beneath it is discarded with no warning.

The code comment frames this as intentional (skipping a ## Notes block), and that intent is reasonable. The problem is the blast radius: the rule silently discards goal content too, and ## Detail is an entirely natural heading for the long-form body of a goals file.

Affected code

GenerateTelosSummary.ts L174-190 (current main):

const bucketOf = (heading: string): Bucket | null => {
  const h = heading.toLowerCase();
  if (h.includes('active')) return 'active';
  if (h.includes('deferred') || h.includes('ongoing')) return 'deferred';
  if (h.includes('completed') || h.includes('done')) return 'completed';
  return null; // unrecognized heading (e.g. "## Notes") — not goal content
};
// ...
if (m) { current = bucketOf(m[1]); continue; }
if (current) sectionLines[current].push(line);   // <- null bucket: line vanishes

Reproduction

A GOALS.md in the common "quick list + detail" shape:

## Active Goals (Quick List)

- **G0**: Ship the thing
- **G1**: Ship the other thing

## Detail

### G0: Ship the thing
Long-form prose explaining G0.

### G1: Ship the other thing
Long-form prose explaining G1.

Result: only the quick-list bullets survive. bucketOf("Detail") returns null, so the entire ## Detail block — the substantive part of the file — is dropped, silently. Nothing warns, nothing errors, and the generated summary looks perfectly plausible.

If the goals are only written under ## Detail (no quick list), the summary renders zero goals while the file is clearly full of them. That's the same class of failure as #1169 and #1199, which suggests this parser keeps getting bitten by heading-shape assumptions.

Expected

Content under an unrecognized heading should not disappear without a trace. Any of these would fix it:

  1. Default unrecognized headings to active rather than null (fail-open — most consistent with "content before any recognized heading is active", which the code already does).
  2. Keep the drop but console.warn which heading and how many lines were discarded, so it's visible.
  3. Allowlist the skip (notes, archive) instead of denylisting by omission, so only explicitly-ignorable blocks are dropped.

Impact

Silent, undetectable data loss in the generated summary. The user's goals file is intact on disk, so nothing looks broken; the goals simply never reach the boot context that consumes PRINCIPAL_TELOS.md. Found this on an install where the entire detailed-goals block had been invisible to the generator for weeks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions