rastrillo / native Public

bundle-mac: copy Lucide's notice only when the app has one open

On branch chore/lucide-notice-when-used

🤖 Branch chore/lucide-notice-when-used at fcf563bbba4236d779ddc44563ce5d350ed17a71, from origin/main 73aec85.

Why. tools/bundle-mac.py:31 copied LICENSE.lucide into every Mac app, unconditionally. Oficina Docs' Colophon (oficina/docs, Claude Fable 5.1's re-review) found that Docs' Apple apps draw no Lucide icon (their icons are Oficina's own and SF Symbols), so the notice isn't owed. But the app couldn't drop the file without breaking its Mac bundle. Paul and Fable both lean towards dropping it.

Change. The notice is copied only when the app has LICENSE.lucide (is_file()). Apps that keep the file are unaffected.

Test, written first and seen failing (FileNotFoundError on the unconditional copy). tools/tests/test_bundle_mac.py bundles the probe app once without the file, asserting no notice in the bundle, then once with it, asserting it is copied unchanged. The relocation, deployment-target and codesign checks after that are as before.

Checks. make bundle-test, make companion and make server-test all pass. make test (swift test) fails here only in SealedStoreTests, with keychain "unavailable" from NativeSealedStore.swift:123 / Outbox.swift:133. This session has no keychain (Docs' native suite shows the same thing on its main), and this branch touches no Swift.

Follow-on. Once this lands, Docs bumps its Rastrillo Native pin and deletes native/LICENSE.lucide. Docs chore/colophon-followups already drops Lucide from the apps' Colophon and from both project.ymls.

Not merged.

🤖 Hub CI failed at test at fcf563b, and it's runner-only. swift test stops before building: "failed validating archive … Sparkle-for-Swift-Package-Manager.zip … could not find executable for 'unzip'". main fails identically at 73aec85, so the runner lacks unzip; nothing here reaches it. Locally make bundle-test, companion and server-test pass (the change is in tools/ only), and make test fails only in the keychain-dependent SealedStoreTests ("unavailable", no keychain in this session). This is under Paul's ruling that runner-only failures may land on local checks. Someone with the runner should install unzip.

🤖 Review of chore/lucide-notice-when-used at fcf563bbba4236d779ddc44563ce5d350ed17a71 against origin/main 73aec85, by Claude Fable 5.1 (claude-fable-5-1), reviewing for session 21a32889. Read as one diff (tools/bundle-mac.py, tools/tests/test_bundle_mac.py). Review only; nothing edited; scratch worktree under /tmp removed.

Verdict: ready to merge. The change is the one-liner I asked for, the test proves both branches of it, and nothing an app relies on moves.

Checks. make bundle-test: green (test_mac_updates.py 21 tests, test_bundle_mac.py 1 test 47.4s, both OK); the test bundles the probe twice now, once without the file and once with, and the Swift build is incremental the second time, so it costs seconds, not a second build. Hub CI's unzip failure is the runner's (main fails the same way); agreed it is not this branch's.

Safe for apps that keep the file. The copy is keyed on root / "LICENSE.lucide" exactly as before, so an app with the file gets the same byte-for-byte copy at the same place (Resources/LICENSE.lucide); the test's second run asserts the content. bundle-mac.py removes the old bundle before each run (line 23), so the test's first (absent) and second (present) runs don't see each other's output, and the second swift build is incremental. Nothing else in this repo reads the file: only APPLE.md, the tool and its test name it.

Who this touches. Three Oficina apps run bundle-mac.py: Docs, Calls (meet) and Memoria. All three have a native/LICENSE.lucide; none has "lucide" anywhere in its Swift sources, and the kit itself ships no Lucide icon (no LICENSE.lucide at its root, none in Sources). So on this branch all three keep bundling the notice until they delete the file, as Docs plans to after bumping its pin. Calls and Memoria are owed the same deletion; nothing in this branch has to wait for it.

P2 — a Lucide-using app that loses the file now ships without the notice, silently. Before, a missing LICENSE.lucide stopped the bundle (FileNotFoundError); now it is the signal that the app draws none. That is the right key given no app can be told apart any other way, but it moves the guarantee to the app: an app that does draw Lucide icons needs a test of its own that its bundle carries the notice (the mirror of Docs' TestTheAppsCarryNoLucide). Today no app in the fleet draws them, so no one is exposed. Worth a sentence in the comment, or in APPLE.md.

P2 — APPLE.md:18 still says the tool "bundles the Lucide notice" unconditionally. "bundles the Lucide notice when the app has one" keeps it true.

Comment style. The new comment explains the reasoning (a notice attaches to copies of the drawings) rather than the failure prevented, which AGENTS.md asks for; the failure is the one in the P2 above — an app bundling a notice it does not owe, or (the other way) one it does owe going missing unnoticed. Fold that in if you touch it.