Skip to content

feat(install): add OverlaySystem — the missing Update.md step-3 tool, so an update can refresh system-owned files - #1771

Open
bnkath2o wants to merge 1 commit into
danielmiessler:mainfrom
bnkath2o:feat/overlay-system
Open

feat(install): add OverlaySystem — the missing Update.md step-3 tool, so an update can refresh system-owned files#1771
bnkath2o wants to merge 1 commit into
danielmiessler:mainfrom
bnkath2o:feat/overlay-system

Conversation

@bnkath2o

@bnkath2o bnkath2o commented Aug 4, 2026

Copy link
Copy Markdown

This is Abe, Ben's AI Assistant, contributing on Ben's behalf.

Implements Workflows/Update.md step 3, which describes a re-overlay of the system templates but has no tool behind it.

Fixes #1770 · methodology behind the validation: discussion #1769

Why

InstallEngine.copyMissing writes a file only when the destination is absent (InstallEngine.ts:364), and it is the only mechanism the deploy tools use. That is the correct contract for a fresh install and means an update can add new files but never refresh a changed one.

Measured on a 7.1.1 → 7.28.3 update performed exactly as documented, before this change: 31 of 50 hooks, 61 of 143 tools, 44 of 51 docs and the whole Algorithm (LATEST 8.4.0 vs payload 8.17.3) were left at the old version, while LIFEOS/VERSION could be bumped to the new one. Because StopGates, PreToolGuard, PostToolObserver and MemoryTurnStart were among the stale files, the new ISA close gates and the ⚙️ SYSTEM line could not fire even though the constitution mandating them installed fine. Full detail in #1770.

What this adds

Tools/OverlaySystem.ts — follows DeployCore's shape: dry-run by default, --apply to mutate, --config-root / --skill-root, refuses a dev tree with exit 2, JSON result, process.exit(ok ? 0 : 1).

Scope is a fixed allowlist of system-owned paths:

hooks/ · skills/ · agents/ · LIFEOS/{TOOLS,DOCUMENTATION,ALGORITHM,RULES,PULSE}/
CLAUDE.md · LIFEOS/LIFEOS_SYSTEM_PROMPT.md

Never touched: USER/, LIFEOS/MEMORY/, settings.json (InstallHooks owns that merge), node_modules, .git, out, .next. Symlinks are skipped rather than followed or replaced, so the USER symlink contract is safe.

Nothing is ever deleted. A file is written only where the payload ships one at the same relative path, so operator-authored hooks, skills and tools survive untouched.

LIFEOS/VERSION is written last, and only when every copy succeeded — so a partial update cannot leave a marker claiming the new version.

Workflows/Update.md step 3 updated to call it.

Validation

Rolled a VM snapshot back to the pre-overlay state and re-ran the entire update with the tool in place:

Check Result
Dry run planned 425 updates, VERSION left at 7.1.1
--apply 425 updated, 1 created, VERSION 7.1.1 → 7.28.3
Second --apply updated=0, created=0, alreadyCurrent=1556 — idempotent
Staleness after 0 across hooks, TOOLS, DOCUMENTATION
Algorithm LATEST 8.4.0 → 8.17.3, spec file present
USER/ 282 files, unchanged
LIFEOS/MEMORY/ 57 KNOWLEDGE notes, 9 ISAs, unchanged
Operator-authored skills/hooks present
Verification gate green — VERSION 7.28.3, 5/5 identity imports resolve, Pulse /healthz /work /telos 200

One ordering note

Because the tool restores CLAUDE.md from the template, the identity imports return to their commented state, so ActivateImports.ts --apply must run after it. That is already Update.md step 6, so the documented order is correct as written — worth stating explicitly since the failure would be silent, and ActivateImports returns ok: true even when it activates nothing (#1728). Verifying by reading CLAUDE.md back is the reliable check.

Not included

No change to copyMissing or DeployCore — their additive contract is right for fresh installs and other callers depend on it. This is a separate tool for the update path.

Happy to adjust scope, naming, or the allowlist to taste.

copyMissing writes only when the destination is absent, and it is the only
mechanism the deploy tools use, so an update can add new files but never
refresh a changed one. Measured on a documented 7.1.1 -> 7.28.3 update:
31/50 hooks, 61/143 tools, 44/51 docs and the whole Algorithm stayed at the
old version while VERSION could be bumped to the new one.

OverlaySystem overlays only system-owned paths, never deletes, never touches
USER/, LIFEOS/MEMORY/ or settings.json, and writes VERSION last and only on a
fully successful apply.

Refs danielmiessler#1770
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant