Summary
GenerateTelosSummary.ts copies unfilled template stubs like [Another key talking point you'd add] or [A formative experience, yours to add] into PRINCIPAL_TELOS.md as if they were the principal's real narratives, traumas, and models. Since PRINCIPAL_TELOS.md is @-imported into every session, these placeholder lines load as always-on context: token cost with zero signal, and the model reads template prose as if it were user identity data.
This is the same defect class as #1528 (template text rendered as principal content), but a different marker: #1528's suggested guard keys on the literal (sample) string, while the USER templates also ship square-bracket fill-in stubs ([...]) that carry no (sample) marker. As of current HEAD (LifeOS/install/LIFEOS/TOOLS/GenerateTelosSummary.ts), neither guard is present in the shipped file.
Repro
- Scaffold USER/TELOS from the shipped templates, fill in some sections, leave others as delivered (the realistic partial-onboarding state).
- Run
bun ~/.claude/LIFEOS/TOOLS/GenerateTelosSummary.ts.
PRINCIPAL_TELOS.md renders stub entries as content, e.g.:
- N3: [Another key talking point you'd add]
- **TR0**: [A formative experience, yours to add]
- [A model for understanding human behavior]
Confirmed on a live 7.1.1 install: 8 placeholder lines loaded in every session until removed.
Suggested fix
In parseItems() (and the prose path), skip any entry whose text, after trimming, matches ^\[.*\]$ — pure bracket-stub entries are template scaffolding by definition. Optionally emit them as an end-of-file HTML comment (<!-- unfilled: N3, TR0, TR1 -->) so the principal can still see what's left to fill without paying always-on tokens for it.
Related, minor (say if you want this split out)
truncate() cuts at a hard character budget mid-thought and appends ... (60/75 chars). For load-bearing Mission/Goal lines the ellipsis routinely lands mid-clause, so the always-on summary carries sentence fragments. Cutting at a sentence/clause boundary within the same budget would keep the compression while making every surviving line self-contained.
Summary
GenerateTelosSummary.tscopies unfilled template stubs like[Another key talking point you'd add]or[A formative experience, yours to add]intoPRINCIPAL_TELOS.mdas if they were the principal's real narratives, traumas, and models. SincePRINCIPAL_TELOS.mdis@-imported into every session, these placeholder lines load as always-on context: token cost with zero signal, and the model reads template prose as if it were user identity data.This is the same defect class as #1528 (template text rendered as principal content), but a different marker: #1528's suggested guard keys on the literal
(sample)string, while the USER templates also ship square-bracket fill-in stubs ([...]) that carry no(sample)marker. As of current HEAD (LifeOS/install/LIFEOS/TOOLS/GenerateTelosSummary.ts), neither guard is present in the shipped file.Repro
bun ~/.claude/LIFEOS/TOOLS/GenerateTelosSummary.ts.PRINCIPAL_TELOS.mdrenders stub entries as content, e.g.:Confirmed on a live 7.1.1 install: 8 placeholder lines loaded in every session until removed.
Suggested fix
In
parseItems()(and the prose path), skip any entry whose text, after trimming, matches^\[.*\]$— pure bracket-stub entries are template scaffolding by definition. Optionally emit them as an end-of-file HTML comment (<!-- unfilled: N3, TR0, TR1 -->) so the principal can still see what's left to fill without paying always-on tokens for it.Related, minor (say if you want this split out)
truncate()cuts at a hard character budget mid-thought and appends...(60/75 chars). For load-bearing Mission/Goal lines the ellipsis routinely lands mid-clause, so the always-on summary carries sentence fragments. Cutting at a sentence/clause boundary within the same budget would keep the compression while making every surviving line self-contained.