Summary
applyProposalEdit() uses the incoming target_file string as-is. When that string is relative, it resolves against the caller's current working directory; when it is absolute but wrong, nothing corrects it. Either way the function returns target file missing and the proposal is dropped — including high-confidence ones — with no louder signal than a status string.
Root cause
LIFEOS/PULSE/lib/telegram-proposals.ts:
export function applyProposalEdit(targetFile: string, editText: string): { ok: true } | { ok: false; reason: string } {
if (!existsSync(targetFile)) return { ok: false, reason: `target file missing: ${targetFile}` };
Two ways this fails in practice:
- Relative target —
"LIFEOS/USER/CONFIG/OPERATIONAL_RULES.md" resolves against process.cwd(). The reviewer that produces proposals can run from a launchd agent, whose working directory is not the LifeOS root, so the same proposal applies or vanishes depending on who invoked the process.
- Wrong-absolute target — the model writing the proposal emits a plausible but incorrect absolute path (a different home segment, or
LifeOS where the directory is LIFEOS). It passes the "is absolute" smell test and fails existsSync.
Both produce the same outcome: a proposal that was correct in content is discarded for an addressing problem.
Proposed fix
Every real proposal target lives under ~/.claude. Re-anchor on the first case-insensitive LIFEOS/ segment instead of trusting the string:
// The target_file that reaches us is unreliable in two ways, both of which used to drop
// high-confidence proposals silently: relative (resolved against the caller's cwd — a
// launchd job runs from anywhere) and wrong-absolute (a hallucinated home or casing).
// Both are cured by re-anchoring on the first case-insensitive "LIFEOS/" segment.
export function resolveProposalTarget(targetFile: string): string {
const m = targetFile.match(/(?:^|\/)(LIFEOS\/.*)$/i);
if (m) return join(HOME, ".claude", m[1].replace(/^LIFEOS/i, "LIFEOS"));
return isAbsolute(targetFile) ? targetFile : join(HOME, ".claude", targetFile);
}
then call applyProposalEdit(resolveProposalTarget(p.target_file), …).
Running locally since 2026-07-25. Worth considering alongside it: target file missing deserves to be louder than a status field, since it is the one failure that silently discards work the pipeline already paid for.
Summary
applyProposalEdit()uses the incomingtarget_filestring as-is. When that string is relative, it resolves against the caller's current working directory; when it is absolute but wrong, nothing corrects it. Either way the function returnstarget file missingand the proposal is dropped — including high-confidence ones — with no louder signal than a status string.Root cause
LIFEOS/PULSE/lib/telegram-proposals.ts:Two ways this fails in practice:
"LIFEOS/USER/CONFIG/OPERATIONAL_RULES.md"resolves againstprocess.cwd(). The reviewer that produces proposals can run from a launchd agent, whose working directory is not the LifeOS root, so the same proposal applies or vanishes depending on who invoked the process.LifeOSwhere the directory isLIFEOS). It passes the "is absolute" smell test and failsexistsSync.Both produce the same outcome: a proposal that was correct in content is discarded for an addressing problem.
Proposed fix
Every real proposal target lives under
~/.claude. Re-anchor on the first case-insensitiveLIFEOS/segment instead of trusting the string:then call
applyProposalEdit(resolveProposalTarget(p.target_file), …).Running locally since 2026-07-25. Worth considering alongside it:
target file missingdeserves to be louder than a status field, since it is the one failure that silently discards work the pipeline already paid for.