From 81cbc5f4de8d8d7268c4979befbdf42cf45d574b Mon Sep 17 00:00:00 2001
From: OLAF Maintainers <10076938+kengio@users.noreply.github.com>
Date: Wed, 26 Aug 2026 16:03:46 +0700
Subject: [PATCH] chore: consolidate to one repository, and rename the masthead
art
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Development happened in a private repository; this one was created from an
orphan-root commit carrying a curated subset, with an exclude list naming what
stayed behind and a guard script to catch anything merged here first from being
silently reverted by the next release. That arrangement is ending: this
repository becomes the only one.
Everything worth keeping therefore has to arrive before the private one goes
away. Seventeen paths existed nowhere else; these eleven are the ones with
lasting value:
- the five diagram pairs (apply semantics, destructive utilities, mode
lifecycle, pipeline, pipeline branching)
- scripts/gen-olaf-diagrams.py, which generates them
They were withheld because no published document referenced them — never
because a check objected. The exclude list said so in as many words: "None of
these are excluded for safety — the release scanner reports no finding against
any of them." The generator does not produce the four diagram pairs already
published here, so nothing shipped was ever at risk of becoming
unregenerable; these five simply had no copy outside one laptop.
The exclude list and the mirror-back guard are deliberately NOT brought over.
Both exist to manage two repositories that cannot merge into each other. With
one repository there is no subtraction to describe and no drift to guard
against, and carrying them would leave instructions for a process that no
longer runs.
Masthead art renamed olaf-lockup-* to olaf-banner-*. The bytes were replaced in
the previous change but the filenames were not, and GitHub serves README images
through a cache keyed on URL — so every viewer kept getting the previous image
from an unchanged address. A new name is the only thing that reliably
invalidates that. It also describes the file better: this is a banner.
README, brand guidelines, the asset README and PROVENANCE all follow the
rename, and every recorded hash was re-verified against the file on disk.
---
CHANGELOG.md | 35 ++-
README.md | 4 +-
assets/brand/PROVENANCE.md | 4 +-
assets/brand/README.md | 2 +-
...f-lockup-dark.png => olaf-banner-dark.png} | Bin
...lockup-light.png => olaf-banner-light.png} | Bin
docs/assets/apply-semantics-dark.svg | 47 ++++
docs/assets/apply-semantics-light.svg | 47 ++++
docs/assets/destructive-utilities-dark.svg | 41 +++
docs/assets/destructive-utilities-light.svg | 41 +++
docs/assets/mode-lifecycle-dark.svg | 61 +++++
docs/assets/mode-lifecycle-light.svg | 61 +++++
docs/assets/pipeline-branching-dark.svg | 46 ++++
docs/assets/pipeline-branching-light.svg | 46 ++++
docs/assets/pipeline-dark.svg | 63 +++++
docs/assets/pipeline-light.svg | 63 +++++
docs/brand-guidelines.md | 6 +-
scripts/gen-olaf-diagrams.py | 240 ++++++++++++++++++
18 files changed, 798 insertions(+), 9 deletions(-)
rename assets/brand/{olaf-lockup-dark.png => olaf-banner-dark.png} (100%)
rename assets/brand/{olaf-lockup-light.png => olaf-banner-light.png} (100%)
create mode 100644 docs/assets/apply-semantics-dark.svg
create mode 100644 docs/assets/apply-semantics-light.svg
create mode 100644 docs/assets/destructive-utilities-dark.svg
create mode 100644 docs/assets/destructive-utilities-light.svg
create mode 100644 docs/assets/mode-lifecycle-dark.svg
create mode 100644 docs/assets/mode-lifecycle-light.svg
create mode 100644 docs/assets/pipeline-branching-dark.svg
create mode 100644 docs/assets/pipeline-branching-light.svg
create mode 100644 docs/assets/pipeline-dark.svg
create mode 100644 docs/assets/pipeline-light.svg
create mode 100755 scripts/gen-olaf-diagrams.py
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)