Skip to content

reload: fix infinite reload loop and spurious rebuilds from .devenv/#2806

Open
ndam-hexagon wants to merge 1 commit into
cachix:mainfrom
ndam-hexagon:dev/ndam-hexagon/monorepo-fix-devenv-watching-files
Open

reload: fix infinite reload loop and spurious rebuilds from .devenv/#2806
ndam-hexagon wants to merge 1 commit into
cachix:mainfrom
ndam-hexagon:dev/ndam-hexagon/monorepo-fix-devenv-watching-files

Conversation

@ndam-hexagon
Copy link
Copy Markdown
Contributor

@ndam-hexagon ndam-hexagon commented May 8, 2026

Problem

devenv shell self-triggered hot-reload in an infinite loop after the first reload, and lib.fileset.fromSource ./. (or any other readDir on a parent of .devenv/) caused spurious cache invalidations and rebuilds.

Both came from the same root cause: devenv's own dotfile churn was leaking into Nix's tracked-input set, so every evaluation invalidated the previous one's cache.

Fix

Exclude .devenv/ from the reload watch set and the eval cache's tracked inputs, keeping .devenv/state/ ($DEVENV_STATE) so files users persist there still trigger reload.

@domenkozar
Copy link
Copy Markdown
Member

Maybe we should skip individual devenv files? I'm worried that someone might store something into DEVENV_STATE and expect the reload to work.

@ndam-hexagon ndam-hexagon force-pushed the dev/ndam-hexagon/monorepo-fix-devenv-watching-files branch from 6048614 to 63a79f8 Compare May 28, 2026 11:47
@ndam-hexagon ndam-hexagon changed the title reload: exclude devenv state dir from hot-reload watch set reload: exclude devenv dotfile from eval inputs and watch set May 28, 2026
@ndam-hexagon ndam-hexagon force-pushed the dev/ndam-hexagon/monorepo-fix-devenv-watching-files branch from 63a79f8 to 9bb171b Compare May 28, 2026 12:26
@ndam-hexagon ndam-hexagon changed the title reload: exclude devenv dotfile from eval inputs and watch set reload: fix infinite reload loop and spurious rebuilds from .devenv/ May 28, 2026
@domenkozar domenkozar requested a review from sandydoo May 28, 2026 15:28
`lib.fileset.fromSource ./.` (and any other `readDir` on a parent of
`.devenv/`) was dragging devenv's own churn into the Nix tracked-input
set: the eval-cache SQLite db + WAL/SHM are rewritten on every
evaluation, the tasks db on every task run, and shell-env.sh /
imports.txt / generated bootstrap files on every build. Tracked
inputs that change every run mean cache validity is poisoned and the
reload watcher self-triggers in an infinite loop after the first
reload.

Exclude the whole devenv dotfile from both the eval cache's tracked
inputs (CachingConfig.excluded_paths) and the reload watcher
(is_watchable_input in reload::owner). To preserve the documented
$DEVENV_STATE contract, carve out `<dotfile>/state/` via
CachingConfig.excluded_path_exceptions and the equivalent predicate
in the watcher: files users persist there still trigger reload and
cache invalidation.

The carve-out would otherwise re-admit devenv-managed leaves under
`state/` — the tasks-cache sqlite db (rewritten on every task run)
and the git-hooks state dir (rewritten on every reload) — and
reintroduce the same loop scoped to state/. Switch `ops_to_inputs`
to longest-prefix-match between `excluded_paths` and
`excluded_path_exceptions`: the most specific rule wins, ties favor
the exception. Callers can then list `<dotfile>/state/tasks.db`,
`tasks.db-wal`, `tasks.db-shm`, and `git-hooks` back in
`excluded_paths` and have them override the broader state exception.
`is_watchable_input` mirrors the same leaf list as defense in depth
in case a stale eval-cache row predates the filter.

`Path::starts_with` matches on components, so each sqlite sibling
(`-wal`, `-shm`) is its own component and is listed explicitly — a
`tasks.db` prefix would not cover them.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ndam-hexagon ndam-hexagon force-pushed the dev/ndam-hexagon/monorepo-fix-devenv-watching-files branch from 9bb171b to be168ec Compare May 29, 2026 14:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants