diff --git a/CHANGELOG.md b/CHANGELOG.md
index b519bc0..452622a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,7 +6,40 @@ version `1.0.0` maps to release tag `v1.0.0`.
## [Unreleased]
-No changes yet.
+### Added
+
+- The five diagram pairs the release build used to hold back — apply semantics, destructive
+ utilities, mode lifecycle, pipeline, pipeline branching — and `scripts/gen-olaf-diagrams.py`,
+ which generates them. They were withheld because no published document referenced them, never
+ because a check objected: the release scanner reported no finding against any of them.
+- `README.md` regained **What is OneLake security?**, **Why OLAF?** and a **Roadmap** checklist,
+ along with the Arctic Owl mascot. A second badge row states what CI proves and what OLAF runs on.
+- A roadmap entry for a local authoring tool that would validate and build a config against a real
+ workspace from a developer machine, with the conditions that block it.
+- The example notebooks are complete again: `olaf_cookbook` carries 33 code cells and
+ `olaf_master_workflow` the full stage-by-stage pipeline, instead of 3 each.
+
+### Changed
+
+- **This repository is now the only one.** Development happened in a private repository whose
+ history was withheld from an orphan-root release commit. Everything worth keeping is here, so the
+ subtraction machinery — an exclude list, a mirror-back guard against silently reverting anything
+ merged here first — has no remaining purpose and does not travel with it.
+- The masthead art is renamed `olaf-banner-light.png` / `olaf-banner-dark.png`. It was
+ `olaf-lockup-*`, and overwriting those files left every cache serving the previous image from an
+ unchanged URL. A new name is the only thing that reliably invalidates it.
+- The social preview carries the wordmark, the project name and the plan → review → apply sequence,
+ where it was previously the logo on a plain ground.
+
+### Fixed
+
+- `olaf_master_workflow` read `deleted` from the apply envelope, a key the runtime renamed to
+ `omitted_role_candidates`. It printed `deleted 0` on every run regardless of what the payload
+ actually left out.
+- The same notebook sorted per-role verdicts on `{"delete": 0, ...}`. The runtime emits `omit` and
+ never `delete`, so omitted roles fell to the default rank and sorted last under a heading that
+ promised them first.
+- `README.md` no longer pins a version number in prose; the release badge reads the tag.
## [1.0.0] - 2026-08-26
diff --git a/README.md b/README.md
index 84a6656..d2d6c72 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
-
-
+
+
diff --git a/assets/brand/PROVENANCE.md b/assets/brand/PROVENANCE.md
index 4c0feda..f8dd239 100644
--- a/assets/brand/PROVENANCE.md
+++ b/assets/brand/PROVENANCE.md
@@ -9,8 +9,8 @@ personal attribution or private working files.
|---|---|---|
| `olaf-logo.png` | `68f46d4054cce80b23f5c8255f5f0c2c306da116adbbe3c094ca0ec0d78efa28` | 512 × 512 px |
| `olaf-mascot.png` | `3078c87bd9d9a74030fb73df034f17380d01387a8dde29edf6dca5aa19740f9c` | 512 × 512 px |
-| `olaf-lockup-light.png` | `f005a1b558ae309a05aacf59097a57022d91f86c45f146469f68db213dc29325` | 1280 × 640 px |
-| `olaf-lockup-dark.png` | `7ad09f4cf95564e35a5270050ae8dda75553dae1c8f8aa6b892679527cf6b94e` | 1280 × 640 px |
+| `olaf-banner-light.png` | `f005a1b558ae309a05aacf59097a57022d91f86c45f146469f68db213dc29325` | 1280 × 640 px |
+| `olaf-banner-dark.png` | `7ad09f4cf95564e35a5270050ae8dda75553dae1c8f8aa6b892679527cf6b94e` | 1280 × 640 px |
| `olaf-social-preview.png` | `c5d1fec2a4925a5babad59920c0fd5b475778d288c6285efee45a6ac12ce0e0e` | 1280 × 640 px |
## Origin and transformations
diff --git a/assets/brand/README.md b/assets/brand/README.md
index 06bce3f..0a4b16e 100644
--- a/assets/brand/README.md
+++ b/assets/brand/README.md
@@ -6,7 +6,7 @@ Use only the assets in this directory for public OLAF surfaces.
|---|---|
| `olaf-logo.png` | Primary mark (arctic owl in an ice shield) — repository avatar, docs header, social avatar, badges ≥ 64 px |
| `olaf-mascot.png` | Arctic Owl Sentinel mascot — README hero, launch and community artwork |
-| `olaf-lockup-light.png` / `olaf-lockup-dark.png` | Horizontal lockup (mark + wordmark) — README masthead and page headers, per color scheme |
+| `olaf-banner-light.png` / `olaf-banner-dark.png` | Horizontal banner (mark + wordmark) — README masthead and page headers, per color scheme |
| `olaf-social-preview.png` | Privacy-safe 1200 × 630 repository social preview — OLAF mark only, no Microsoft logo, product icon, or personal avatar |
The source of truth for usage, messaging, spacing, and legal separation is
diff --git a/assets/brand/olaf-lockup-dark.png b/assets/brand/olaf-banner-dark.png
similarity index 100%
rename from assets/brand/olaf-lockup-dark.png
rename to assets/brand/olaf-banner-dark.png
diff --git a/assets/brand/olaf-lockup-light.png b/assets/brand/olaf-banner-light.png
similarity index 100%
rename from assets/brand/olaf-lockup-light.png
rename to assets/brand/olaf-banner-light.png
diff --git a/docs/assets/apply-semantics-dark.svg b/docs/assets/apply-semantics-dark.svg
new file mode 100644
index 0000000..9aaeadb
--- /dev/null
+++ b/docs/assets/apply-semantics-dark.svg
@@ -0,0 +1,47 @@
+
diff --git a/docs/assets/apply-semantics-light.svg b/docs/assets/apply-semantics-light.svg
new file mode 100644
index 0000000..55a2c56
--- /dev/null
+++ b/docs/assets/apply-semantics-light.svg
@@ -0,0 +1,47 @@
+
diff --git a/docs/assets/destructive-utilities-dark.svg b/docs/assets/destructive-utilities-dark.svg
new file mode 100644
index 0000000..668215e
--- /dev/null
+++ b/docs/assets/destructive-utilities-dark.svg
@@ -0,0 +1,41 @@
+
diff --git a/docs/assets/destructive-utilities-light.svg b/docs/assets/destructive-utilities-light.svg
new file mode 100644
index 0000000..da0f29f
--- /dev/null
+++ b/docs/assets/destructive-utilities-light.svg
@@ -0,0 +1,41 @@
+
diff --git a/docs/assets/mode-lifecycle-dark.svg b/docs/assets/mode-lifecycle-dark.svg
new file mode 100644
index 0000000..425303c
--- /dev/null
+++ b/docs/assets/mode-lifecycle-dark.svg
@@ -0,0 +1,61 @@
+
diff --git a/docs/assets/mode-lifecycle-light.svg b/docs/assets/mode-lifecycle-light.svg
new file mode 100644
index 0000000..14fd43a
--- /dev/null
+++ b/docs/assets/mode-lifecycle-light.svg
@@ -0,0 +1,61 @@
+
diff --git a/docs/assets/pipeline-branching-dark.svg b/docs/assets/pipeline-branching-dark.svg
new file mode 100644
index 0000000..682b83d
--- /dev/null
+++ b/docs/assets/pipeline-branching-dark.svg
@@ -0,0 +1,46 @@
+
diff --git a/docs/assets/pipeline-branching-light.svg b/docs/assets/pipeline-branching-light.svg
new file mode 100644
index 0000000..dd3ba06
--- /dev/null
+++ b/docs/assets/pipeline-branching-light.svg
@@ -0,0 +1,46 @@
+
diff --git a/docs/assets/pipeline-dark.svg b/docs/assets/pipeline-dark.svg
new file mode 100644
index 0000000..95e4fe4
--- /dev/null
+++ b/docs/assets/pipeline-dark.svg
@@ -0,0 +1,63 @@
+
diff --git a/docs/assets/pipeline-light.svg b/docs/assets/pipeline-light.svg
new file mode 100644
index 0000000..cde0a2b
--- /dev/null
+++ b/docs/assets/pipeline-light.svg
@@ -0,0 +1,63 @@
+
diff --git a/docs/brand-guidelines.md b/docs/brand-guidelines.md
index 175401a..b9b7808 100644
--- a/docs/brand-guidelines.md
+++ b/docs/brand-guidelines.md
@@ -108,7 +108,7 @@ through color alone; pair status colors with text or an icon.
|---|---|
| `olaf-logo.png` | Primary mark — avatars, docs headers, badges ≥ 64px |
| `olaf-mascot.png` | Mascot artwork — README hero, launch and community material |
-| `olaf-lockup-light.png` / `olaf-lockup-dark.png` | Masthead lockups per color scheme |
+| `olaf-banner-light.png` / `olaf-banner-dark.png` | Masthead banners per color scheme |
| `olaf-social-preview.png` | Repository social preview — OLAF mark only, without third-party logos or product icons |
### Clear space
@@ -149,8 +149,8 @@ See [Legal separation](#legal-separation) below for the identity/affiliation rul
## README usage
-1. Lead with the masthead lockup (`assets/brand/olaf-lockup-light.png` /
- `olaf-lockup-dark.png` via a `` element).
+1. Lead with the masthead banner (`assets/brand/olaf-banner-light.png` /
+ `olaf-banner-dark.png` via a `` element).
2. Follow with one concrete product sentence.
3. Show the plan → review → apply promise before implementation detail.
4. Keep the quick start within the first two screenfuls.
diff --git a/scripts/gen-olaf-diagrams.py b/scripts/gen-olaf-diagrams.py
new file mode 100755
index 0000000..ab48bba
--- /dev/null
+++ b/scripts/gen-olaf-diagrams.py
@@ -0,0 +1,240 @@
+#!/usr/bin/env python3
+"""Emit the light/dark SVG pair for two OLAF diagrams, in the repo's house style.
+
+ scripts/gen-olaf-diagrams.py docs/assets
+
+Regenerates apply-semantics-{light,dark}.svg and destructive-utilities-{light,dark}.svg.
+One generator emits both themes of both diagrams so a pair cannot drift apart — the light
+and dark files differ only by the colour map below, and editing one by hand is how they
+stop matching. Running it against docs/assets reproduces the committed files byte for byte.
+
+House style, copied from docs/assets/pipeline-branching-*.svg:
+ viewBox only (no width/height) · system-ui font stack · role="img" + a full aria-label
+ classes .box .t .s .ln .lbl · rx=11 boxes · stroke-width 2 · markers get a `d` suffix in dark
+"""
+
+import sys
+
+FONT = "system-ui,-apple-system,Segoe UI,Roboto,sans-serif"
+
+# light -> dark, taken from the existing pairs
+DARK = {
+ "#eef1fc": "#1e2540",
+ "#3a4a8c": "#aeb9f0",
+ "#7c8fd6": "#5b68b0",
+ "#e6f7ee": "#16281f",
+ "#237a5c": "#7fe0a8",
+ "#2a9d6c": "#3fbf7a",
+ "#eeeef2": "#262b36",
+ "#4a5262": "#d0d6e0",
+ "#9aa4b2": "#8a94a6",
+ "#fdeaea": "#3a1f22",
+ "#9c3535": "#f0a8a8",
+ "#d97070": "#d97070",
+ "#fcefd6": "#3a2c10",
+ "#9c6a2a": "#efb35e",
+ "#d99a45": "#e0a052",
+ "#f0ebfc": "#2a1f40",
+ "#4a3f8c": "#c3b8f5",
+ "#8e44ad": "#a56fd6",
+ "#5b6472": "#9aa4b2",
+ "#f6f7f9": "#1a1d24",
+ "#e2e5ec": "#2b303c",
+}
+
+
+def head(vb, aria, dark, extra_css=""):
+ sub = DARK["#5b6472"] if dark else "#5b6472"
+ sfx = "d" if dark else ""
+ ln = "#8a94a6"
+ return f'''\n"
+
+
+# ══════════════════════════════════════════════════════════════════════════════
+# B · destructive-utilities
+# ══════════════════════════════════════════════════════════════════════════════
+ARIA_B = (
+ "The blast radius of the two irreversible utilities. reset deletes every data access role on the "
+ "item, including roles config never declared and DefaultReader, so nobody reads the data through "
+ "OneLake security afterwards; it writes a role backup first and aborts without deleting if that "
+ "write fails, and it leaves the control tables alone. cleanup drops all four control tables, "
+ "including the entire audit history, and deletes every file under the security folder, including "
+ "every pre-apply role backup; it leaves the live roles alone. The two interlock: cleanup destroys "
+ "the backups reset depends on, so running cleanup first makes reset unrecoverable. Neither is a "
+ "deployment mode, both are refused from the pipeline entrypoints and are available only "
+ "interactively, by name."
+)
+
+
+def diagram_b(dark):
+ W, H = 748, 404
+ o = head(f"0 0 {W} {H}", ARIA_B, dark)
+
+ # reset()
+ o += box(24, 22, 330, 176, "#fdeaea", "#d97070", dark)
+ o += txt(189, 46, "reset()", "t", "#9c3535", dark=dark)
+ o += txt(189, 66, "destroys ACCESS", "s", dark=dark)
+ o += txt(40, 92, "✕ every data access role on the item", "del", anchor="start", dark=dark)
+ o += txt(52, 110, "config's own, anyone else's, Default*", "s", anchor="start", dark=dark)
+ o += txt(40, 134, "✓ control tables untouched", "kept", anchor="start", dark=dark)
+ o += txt(40, 158, "✓ writes a role backup first", "kept", anchor="start", dark=dark)
+ o += txt(52, 176, "backup write fails → deletes nothing", "s", anchor="start", dark=dark)
+
+ # cleanup()
+ o += box(394, 22, 330, 176, "#f0ebfc", "#8e44ad", dark)
+ o += txt(559, 46, "cleanup()", "t", "#4a3f8c", dark=dark)
+ o += txt(559, 66, "destroys EVIDENCE", "s", dark=dark)
+ o += txt(410, 92, "✕ all four control tables", "del", anchor="start", dark=dark)
+ o += txt(422, 110, "config, mapping, member, the audit history", "s", anchor="start", dark=dark)
+ o += txt(410, 134, "✕ every file under the security folder", "del", anchor="start", dark=dark)
+ o += txt(422, 152, "including every pre-apply role backup", "s", anchor="start", dark=dark)
+ o += txt(410, 176, "✓ live roles untouched", "kept", anchor="start", dark=dark)
+
+ # the interlock — the label sits ABOVE the dashed run, never on it
+ m = "d" if dark else ""
+ o += txt(374, 220, "cleanup() deletes the backups reset() depends on", "del", dark=dark)
+ o += f' \n'
+
+ o += box(24, 266, 700, 54, "#fdeaea", "#d97070", dark)
+ o += txt(
+ 374,
+ 290,
+ "run cleanup() first and reset() becomes unrecoverable",
+ "t",
+ "#9c3535",
+ dark=dark,
+ size=13,
+ )
+ o += txt(
+ 374,
+ 310,
+ "there is no third copy — the backup folder was the recovery path for both",
+ "s",
+ dark=dark,
+ )
+
+ # not a mode
+ o += box(24, 336, 700, 52, "#eeeef2", "#9aa4b2", dark)
+ o += txt(374, 360, "neither is a deployment mode", "t", "#4a5262", dark=dark, size=13)
+ o += txt(
+ 374,
+ 378,
+ "both are refused from the pipeline entrypoints — interactive only, by name",
+ "s",
+ dark=dark,
+ )
+ return o + "\n"
+
+
+if __name__ == "__main__":
+ out = sys.argv[1].rstrip("/")
+ for name, fn in (("apply-semantics", diagram_a), ("destructive-utilities", diagram_b)):
+ for dark in (False, True):
+ p = f"{out}/{name}-{'dark' if dark else 'light'}.svg"
+ open(p, "w", encoding="utf-8").write(fn(dark))
+ print("wrote", p)