Summary
The per-section fail-loud guard in GenerateTelosSummary.ts (L405–L422) resolves section keys through the same lookup as the code it guards. When a TELOS.md heading drifts from LEGACY_FILE_TO_SECTION, both miss it — and the guard reads "the source lookup returned nothing" as "the source has no content," so it stays silent and the section renders empty.
The guard is doing exactly the right thing conceptually; its comment names the failure precisely ("the total-items guard in main() can't see a partial drop"). It just can't observe the one condition it exists to detect.
The trace
loadTelosSections() keys sections by lowercased heading (L74):
sections[title.toLowerCase()] = body.join('\n').trim();
coreChecks looks up the legacy singular key (L410):
['mission', 'Missions', missions.length],
With a TELOS.md that heads the section ## MISSIONS:
keys present: ["missions"]
sections['mission'] -> undefined
(sections['mission'] ?? '') -> ''
condition (…trim().length > 0) -> false // guard does not fire
readTelosFile() misses identically at L98 (return sections[sectionKey] ?? '';), so the section parses to zero items, and main()'s itemLines === 0 check passes because the other sections parsed fine. Exit 0, summary written, one section silently empty.
Why it's worth a look
PRINCIPAL_TELOS.md is @-imported at every session start, so a silently-empty section is absent from the model's boot context until someone opens the file and reads it. On my install a plural heading dropped the Missions section for ~2 weeks before I noticed; the artifact was 1,646 bytes and looked entirely plausible.
Notably it also passed a migration gate I'd written that checked the @-import chain was "non-empty" — 1,646 > 0. Which is really the same mistake as this one, and the reason I think the guard is worth fixing rather than the parser: an existence check can't see a partial drop either.
On whose fault this is
Mine, mostly — the shipped template uses ## Mission (singular) and maps correctly. My TELOS.md says ## MISSIONS, and also combines ## NARRATIVES / PROBLEMS / MODELS under one heading. That's divergence I introduced.
I'd still gently suggest the guard is the right place to catch it: TELOS.md is a hand-authored life document, and the whole point is that people make it theirs. Heading drift from the template seems like the expected steady state rather than an edge case — which is presumably why the guard was written. It just needs to be able to see the drift.
Possible fix
The narrowest version is to have the guard notice source content that no core section claimed, rather than asking about keys it already believes in:
// after coreChecks
const claimed = new Set(coreChecks.map(([key]) => key));
for (const [heading, body] of Object.entries(sections)) {
if (!body.trim()) continue;
const singular = heading.endsWith('s') ? heading.slice(0, -1) : heading;
if (claimed.has(heading) || claimed.has(singular)) continue;
console.error(`⚠️ TELOS heading "${heading}" has content but matches no known section — it will be dropped from the summary.`);
}
That's orphan detection rather than key lookup, so it also surfaces headings the map was never going to know about (mine has a ## FOUNDING INTENT that's silently dropped today — entirely my own doing, but I'd rather have been told).
A plural/singular fallback in readTelosFile() would fix my specific case, but wouldn't help the next person whose headings drift a different way, so the orphan check seems like better value for the same handful of lines.
Happy to open a PR if useful, or to leave it — you may have a cleaner direction in mind for that file, and it's a small enough thing that I don't want to spend your review time on it if it isn't where the project needs attention.
Environment
Linux, main, verified against the contents API today (L98, L405–422, L514–517 as quoted). Came through the PAI → LifeOS 6 upgrade with an existing corpus, which is a reliable way to find this genre of thing.
Thanks as always — and genuinely, the per-section guard being there at all is why this was a 20-minute diagnosis instead of a long one. The intent was already right.
Summary
The per-section fail-loud guard in
GenerateTelosSummary.ts(L405–L422) resolves section keys through the same lookup as the code it guards. When aTELOS.mdheading drifts fromLEGACY_FILE_TO_SECTION, both miss it — and the guard reads "the source lookup returned nothing" as "the source has no content," so it stays silent and the section renders empty.The guard is doing exactly the right thing conceptually; its comment names the failure precisely ("the total-items guard in main() can't see a partial drop"). It just can't observe the one condition it exists to detect.
The trace
loadTelosSections()keys sections by lowercased heading (L74):coreCheckslooks up the legacy singular key (L410):With a
TELOS.mdthat heads the section## MISSIONS:readTelosFile()misses identically at L98 (return sections[sectionKey] ?? '';), so the section parses to zero items, andmain()'sitemLines === 0check passes because the other sections parsed fine. Exit 0, summary written, one section silently empty.Why it's worth a look
PRINCIPAL_TELOS.mdis@-imported at every session start, so a silently-empty section is absent from the model's boot context until someone opens the file and reads it. On my install a plural heading dropped the Missions section for ~2 weeks before I noticed; the artifact was 1,646 bytes and looked entirely plausible.Notably it also passed a migration gate I'd written that checked the
@-import chain was "non-empty" — 1,646 > 0. Which is really the same mistake as this one, and the reason I think the guard is worth fixing rather than the parser: an existence check can't see a partial drop either.On whose fault this is
Mine, mostly — the shipped template uses
## Mission(singular) and maps correctly. MyTELOS.mdsays## MISSIONS, and also combines## NARRATIVES / PROBLEMS / MODELSunder one heading. That's divergence I introduced.I'd still gently suggest the guard is the right place to catch it:
TELOS.mdis a hand-authored life document, and the whole point is that people make it theirs. Heading drift from the template seems like the expected steady state rather than an edge case — which is presumably why the guard was written. It just needs to be able to see the drift.Possible fix
The narrowest version is to have the guard notice source content that no core section claimed, rather than asking about keys it already believes in:
That's orphan detection rather than key lookup, so it also surfaces headings the map was never going to know about (mine has a
## FOUNDING INTENTthat's silently dropped today — entirely my own doing, but I'd rather have been told).A plural/singular fallback in
readTelosFile()would fix my specific case, but wouldn't help the next person whose headings drift a different way, so the orphan check seems like better value for the same handful of lines.Happy to open a PR if useful, or to leave it — you may have a cleaner direction in mind for that file, and it's a small enough thing that I don't want to spend your review time on it if it isn't where the project needs attention.
Environment
Linux,
main, verified against the contents API today (L98, L405–422, L514–517 as quoted). Came through the PAI → LifeOS 6 upgrade with an existing corpus, which is a reliable way to find this genre of thing.Thanks as always — and genuinely, the per-section guard being there at all is why this was a 20-minute diagnosis instead of a long one. The intent was already right.