vitrine

README: document live config reload and its fail-stable semantics

commit 538bf4237fc420e39bb221bb9cc0175073f03709 · parent ac8aaa4b70 · browse this tree
Ximianth, 2026-07-28 15:43:34 UTC

diff --git a/README.md b/README.md
index 4690008..fc1d7a6 100644
--- a/README.md
+++ b/README.md
@@ -38,6 +38,14 @@ exhibits:
 A bad config (parse error, unknown key, missing path, or zero exhibits)
 is a startup error: vitrine refuses to run rather than serve the wrong thing.
 
+Config changes apply live: vitrine watches the config file
+(inotify for immediate pickup, plus a 5-second stat poll as backstop,
+so a change lands within ~5s worst case, usually instantly).
+At runtime the failure mode flips from fail-loud to fail-stable:
+a reload that fails to parse, or names a directory that can't be opened,
+logs a loud REJECTED line and the previous exhibits keep serving untouched.
+Edit freely; a typo mid-edit can't take the server dark.
+
 expose-git
 ----------
 
@@ -52,12 +60,13 @@ Two caveats, read them before enabling:
 - **vitrine writes into that exhibit's `.git`.**
   Dumb-HTTP clone requires `.git/info/refs` and `.git/objects/info/packs`,
   and ordinary commits never maintain them,
-  so vitrine runs `git update-server-info` on the exhibit at startup.
+  so vitrine runs `git update-server-info` on the exhibit at startup
+  and at every successful config reload.
   This is a deliberate exception to vitrine's otherwise strictly read-only stance.
 - **Dumb HTTP has dumb semantics.**
   Clones reflect the refs as of the last `update-server-info` run,
-  so commits made after vitrine started are invisible to clones until it next runs
-  (currently: restart vitrine).
+  so commits made after the last startup or config reload are invisible to clones
+  until the next one (touching the config file suffices to trigger a reload).
   A stale clone succeeds silently at the old tip; there is no warning.
   Concurrent `git gc` in the exhibit can also break an in-flight clone (loudly; retry works).