Version: 7.40.4 (skills/LifeOS/install, the shipped payload)
What's broken
parseGoals() decides whether a goal is active, deferred or completed from the heading of the section it sits under — never from what the goal says about itself.
LIFEOS/TOOLS/GenerateTelosSummary.ts:305-316:
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';
if (h.includes('note')) return null;
// Any other unrecognized heading (e.g. "## Detail") is treated as active
// goal content — never silently discarded (issue #1473).
return 'active';
};
The shipped template has exactly one goals heading, and it contains none of those words —
USER/TELOS/TELOS.md:33:
## GOALS (measurable milestones toward the problems)
So every goal a template-following user writes falls through to return 'active'. The deferred
and completed buckets — both consumed downstream at GenerateTelosSummary.ts:706 and :715 —
are unreachable by construction for anyone who keeps the shipped structure. A goal marked
✅ COMPLETED in its own body still renders under ## Active Goals (2026).
This is not the same defect as #1473. That one is about content under an unrecognized heading being
dropped; the return 'active' fallback is its correct fix and should stay. This is that the
per-goal status is never consulted at all.
Why it matters
PRINCIPAL_TELOS.md is @-imported into every session, so the assistant starts each session
believing finished goals are current priorities. Worse, WorkSweep.ts:579 opens a [Goal] issue
for every goal the summary lists as active with no matching open issue — so the mis-bucketing
manufactures board items on a schedule.
Observed on a real install: three stale goal cards were closed by hand and the hourly sweep
recreated two of them twenty minutes later. The one that stayed closed was the goal that had been
deleted from the source; the two that came back were the ones merely marked done. Deleting
works, marking completed does nothing.
Repro against a clean tree
git clone --depth 1 --branch v7.40.4 https://github.com/danielmiessler/LifeOS.git /tmp/lifeos-clean
cd /tmp/lifeos-clean
# Use the shipped template as-is and mark one shipped sample goal completed:
sed -i 's/^- \*\*G1:\*\* (sample).*/- **G1:** ✅ COMPLETED 2026-06-08 — shipped sample, marked done./' \
LifeOS/install/USER/TELOS/TELOS.md
bun LifeOS/install/LIFEOS/TOOLS/GenerateTelosSummary.ts
sed -n '/## Active Goals/,/^## /p' LifeOS/install/USER/TELOS/PRINCIPAL_TELOS.md
Expected: G1 under a Completed line.
Actual: G1 listed under ## Active Goals, and the Completed section is absent because the
bucket is empty.
Negative control
Rename the section (nothing else) and the same goal moves:
sed -i 's/^## GOALS (measurable milestones toward the problems)/## Completed Goals/' \
LifeOS/install/USER/TELOS/TELOS.md
bun LifeOS/install/LIFEOS/TOOLS/GenerateTelosSummary.ts
Now every goal renders as completed — including the ones that are not. That is the proof the
heading decides and the goal's own text never does.
Suggested fix
Let the item's own body override the heading, keeping bucketOf and its return 'active' default
exactly as they are:
- parse each goal's body (the lines under its
### Gn: heading — parseItems currently keeps only
the heading line, which is why a status written in the body is invisible);
- if the body declares completion or retirement, move it to that bucket; otherwise keep the
heading's verdict.
A file with no status markers then behaves byte-identically to today.
Happy to send a PR if the approach looks right — and happy to be told the heading-based design is
deliberate, in which case the shipped template probably wants ## Active Goals as its heading so
the other two buckets are at least reachable.
Version: 7.40.4 (
skills/LifeOS/install, the shipped payload)What's broken
parseGoals()decides whether a goal is active, deferred or completed from the heading of the section it sits under — never from what the goal says about itself.LIFEOS/TOOLS/GenerateTelosSummary.ts:305-316:The shipped template has exactly one goals heading, and it contains none of those words —
USER/TELOS/TELOS.md:33:So every goal a template-following user writes falls through to
return 'active'. Thedeferredand
completedbuckets — both consumed downstream atGenerateTelosSummary.ts:706and:715—are unreachable by construction for anyone who keeps the shipped structure. A goal marked
✅ COMPLETEDin its own body still renders under## Active Goals (2026).This is not the same defect as #1473. That one is about content under an unrecognized heading being
dropped; the
return 'active'fallback is its correct fix and should stay. This is that theper-goal status is never consulted at all.
Why it matters
PRINCIPAL_TELOS.mdis@-imported into every session, so the assistant starts each sessionbelieving finished goals are current priorities. Worse,
WorkSweep.ts:579opens a[Goal]issuefor every goal the summary lists as active with no matching open issue — so the mis-bucketing
manufactures board items on a schedule.
Observed on a real install: three stale goal cards were closed by hand and the hourly sweep
recreated two of them twenty minutes later. The one that stayed closed was the goal that had been
deleted from the source; the two that came back were the ones merely marked done. Deleting
works, marking completed does nothing.
Repro against a clean tree
Expected:
G1under a Completed line.Actual:
G1listed under## Active Goals, and the Completed section is absent because thebucket is empty.
Negative control
Rename the section (nothing else) and the same goal moves:
sed -i 's/^## GOALS (measurable milestones toward the problems)/## Completed Goals/' \ LifeOS/install/USER/TELOS/TELOS.md bun LifeOS/install/LIFEOS/TOOLS/GenerateTelosSummary.tsNow every goal renders as completed — including the ones that are not. That is the proof the
heading decides and the goal's own text never does.
Suggested fix
Let the item's own body override the heading, keeping
bucketOfand itsreturn 'active'defaultexactly as they are:
### Gn:heading —parseItemscurrently keeps onlythe heading line, which is why a status written in the body is invisible);
heading's verdict.
A file with no status markers then behaves byte-identically to today.
Happy to send a PR if the approach looks right — and happy to be told the heading-based design is
deliberate, in which case the shipped template probably wants
## Active Goalsas its heading sothe other two buckets are at least reachable.