danielmiessler / danielmiessler/LifeOS

late-ISA nudge: the one-shot reset is unreachable when no run is ever registered

Open
#2,074 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
19k
Forks
2.5k
Avg merge
8d 17h
Merged PRs (30d)
1

Description

**File:** `LifeOS/install/hooks/AlgorithmNudge.hook.ts` (@version 3.2.2 on `main`; also 3.1.0)

## The defect

The late-ISA row exists to notice that a session has gone deep with no ISA.
It fires once, and the fire is latched:

- L84 `const LATE_ISA_THRESHOLD = 25; // tool calls with NO registered run (always-on, once)`
- L858 fires only when `!state.lateISAFired && state.toolCallsTotal >= LATE_ISA_THRESHOLD`
- L865 `state.lateISAFired = true`
- L851 the only place the latch clears: `state.lateISAFired = false`, inside `if (state.runWasOpen)`

`runWasOpen` becomes true only once a run has been registered and then closes.
So when no run is ever registered, which is exactly the condition this row is
built to detect, the reset is unreachable by construction. The mechanism that
should report a missing ISA is disabled by the very absence it reports. One
line, then silence for the rest of the session, however long that session runs.

## Observed

256 tool calls over four days. Final saved state for the session:

```json
{"toolCallsTotal": 256, "lateISAFired": true, "runWasOpen": false,
"lastNudgeAt": {"late-isa": 1788514245707}}
```

The row fired once, at call 25, and stayed silent for the remaining 231.
No ISA was created at any point in the session, and no run was ever registered
(`runWasOpen: false` above). The only durable state file for the session was
written on the fourth day, 2026-09-08, and then only because the user asked for
it explicitly; nothing in the system had produced one in the four days before.
The session ran with no context compaction at all: content that had already
been verified and approved was lost inside a regeneration of the deliverable,
not to a summarisation pass.

*Corrected after publication.* An earlier version of this paragraph said the
session went through several context compactions, and called the final-turn
artefact an ISA. A later check of the transcript found no compaction, and the
artefact was a state file, not an ISA. Neither claim had been verified before
it was written.

## Context, not part of the claim above

Reported because it may bear on how the row should behave.

The sidecar `permission-mode` field records `plan` from 2026-09-04 09:04:48 UTC
to 2026-09-08 14:13:31 UTC, the whole four-day span. I infer from that field
that the session ran in plan mode throughout; I have not verified it against
what was actually enforced, and the open question below is why. Three things
about that window:

1. Nothing in LifeOS models plan mode. Grepping `plan.?mode` (case-insensitive)
across `LIFEOS/ALGORITHM/`, `LIFEOS/RULES/`, `LIFEOS/DOCUMENTATION/ISA/`,
`skills/ISA/` and `install/hooks/` returns one hit: a table row in
`AgentSystem.md` mapping the `Plan` agent. No hook is aware of it.

2. `/fork` was refused: *"Can't fork: this session was started with launch flags
(safe or bare mode, a custom system prompt, a tool allowlist, or restricted
settings) that the copy wouldn't inherit."* LifeOS sessions launch with
`--append-system-prompt-file`.

3. On 2026-09-04 at 10:52:03 the model called `ExitPlanMode` and the user
rejected it (`is_error: true`, "The user doesn't want to proceed with this
tool use").

## An open question, stated as open

My first reading was that plan mode made the nudge's instruction impossible to
obey, since an ISA is a file. That reading does not survive the record. On
2026-09-07 at 14:59:38 a `Write` of 535 lines succeeded (`File created
successfully`) while the sidecar `permission-mode` entries immediately before
and after both recorded `plan`, with no permission prompt and no hook decision
anywhere in the session. So either plan mode does not block `Write` in this
configuration, or that field records interface state rather than what is
actually enforced. I have not determined which. The defect described above does
not depend on the answer.

## Directions (not a patch)

- Re-arm on a tool-call budget, not only on run close.
- Treat "no run ever registered" as a condition the row can revisit, rather than
one it can observe only once.
- State in doctrine what the ISA does when writes may be unavailable.

## Related

#1543 (closed) covers a different defect in the same file: the nudge layer being
advisory-only, and unregistered on a stock install. It does not touch the latch.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start in LifeOS/install/hooks/AlgorithmNudge.hook.ts, reading L84 and the late-ISA state handling around L851-L865. Trace how tool-call counts, runWasOpen, and lateISAFired interact, then verify the behavior for a session with no registered run and more than 25 calls. Done means the late-ISA condition can be revisited according to the stated budget direction, with the write-unavailable behavior documented in the relevant doctrine.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
70/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.