📰 NewsMonitor

Apple Seeks Preliminary Injunction Against OpenAI in Trade Secrets Case

Reuters: Apple on Monday asked a U.S. judge for a preliminary injunction barring two former employees ​and OpenAI from accessing, acquiring, using or disclosing alleged confidential information as it moves ahead with its trade secrets case. [...] The iPhone maker also filed a concurrent motion on Monday seeking expedited discovery, including production of documents relating to the defendants’ alleged access ​of Apple’s proprietary and trade secret information. It asked the judge to order the two ​former Apple employees named in the lawsuit, Chang Liu and Tang Yew Tan, to sit for depositions, along with OpenAI employee Yu-Ting Peng and an unnamed OpenAI employee who previously worked at ​Apple. The request for expedited discovery and the depositions, I understand. Apple wants to move fast, and they want to get depositions (especially, I’m sure, with Tan) now. The preliminary injunction request, though, I’m not quite sure what that means. I kind of think it means Apple is trying to bar Tang Tan from working on OpenAI’s hardware projects, period.  ★

The AI Demand Bubble

If you liked this piece, you should subscribe to my premium newsletter. It’s $70 a year, or $7 a month, and in return you get a weekly newsletter that’s usually anywhere from 5,000 to 18,000 words, including vast, detailed analyses of NVIDIA, Anthropic and

Bending Spoons to Buy Airtable for $1.3 Billion

Ivan Mehta, reporting for TechCrunch: In its first acquisition since going public last month, Bending Spoons on Tuesday said that it has agreed to buy spreadsheet and database startup Airtable for $1.28 billion in cash. Founded in 2013, Airtable has so far raised over $1.4 billion over multiple funding rounds. At its peak, during the boom days of 2021, it was valued at over $11 billion, but earlier this year, its shares were said to be trading on the secondary markets at a valuation of $4 billion. With its current net cash-and-cash-equivalents balance, Airtable is now valued at about $2.25 billion, Bending Spoons said. The problem isn’t that Airtable isn’t good product with a good business. According to the announcement, Airtable’s revenue is up to $480 million/year and grew 20 percent year-over-year. That’s good. That’s just not $11-billion-valuation good. In the abstract building a company worth $1 billion is a success; it’s a problem, though, if its financials are such that it needs to justify a valuation an order of magnitude greater than what it’s actually worth.  ★

brew install actions/checkout

In December I went through why uses: is a package manager with no lockfile, no integrity hashes and no transitive visibility, and in April through the run of incidents that followed from that. GitHub’s 2026 security roadmap has since committed to a lockfile, now in preview as gh-actions-lock, and made immutable actions the preferred resolution path. Neither of those changes adds any review between an action author tagging a release and the runner executing it. Homebrew has run that kind of curated index for fifteen years and, as of the immutable-actions rollout, stores its artifacts as OCI manifests on ghcr.io alongside the actions themselves, so I spent some time working out how much of a GitHub Actions registry you could assemble from Homebrew parts. Shared storage Immutable actions and Homebrew bottles are both OCI artifacts on ghcr.io: actions/publish-immutable-action tars the action directory, pushes it as a layer with artifactType: application/vnd.github.actions.package.v1+json, attaches a sigstore bundle through the OCI referrers API, and tags the manifest with the semver, after which a workflow referencing actions/checkout@4.2.2 resolves through pkg.actions.githubusercontent.com instead of the git tarball. brew pr-pull pushes bottles under the same manifest schema at ghcr.io/homebrew/core/ with a com.github.package.type: homebrew_bottle annotation and a sigstore attestation that brew verify checks against Homebrew’s CI identity, so crane manifest ghcr.io/homebrew/core/jq:1.7.1 and crane manifest ghcr.io/actions/checkout:4.2.2 return the same document type, as you’d expect from last week’s post. The comparison table in the December post marked Actions ✗ on integrity hashes, transitive visibility, dependency-tree inspection and immutable versions, and homebrew-core provides all four for its 8,400 formulae through the index rather than the storage: each formula pins a source URL to a sha256, declares dependencies that brew deps --tree can walk, passes brew audit and human review on every change, gets autobumped by livecheck when upstream tags a release, and can carry deprecate! or disable! when it shouldn’t be installed. A tap of actions The index can be a tap, with each formula pinning an action tarball by SHA-256:

class ActionsCheckout < Formula desc "Checks out a repository for a GitHub Actions workflow" homepage "https://github.com/actions/checkout" url "https://github.com/actions/checkout/archive/refs/tags/v4.2.2.tar.gz" sha256 "63e9c07ff6c9ddf3a3b39d30e59f0bf3a..." license "MIT"

livecheck do url :stable strategy :github_latest end

def install prefix.install Dir.children(".") end end

For a JavaScript action that ships a built dist/ in its release tarball, that’s sufficient: the tarball is pinned to a content hash, brew audit and brew verify apply as they would to any formula, and brew bump-formula-pr opens a reviewed PR when checkout tags v4.2.3. Everything above def install is already static data. Homebrew is in the middle of migrating install hooks to declarative steps so that bottle and cask installs need no Ruby evaluation at all, at which point an actions tap could be .json files with no code execution on install. The transitive problem is specific to composite actions, whose action.yml carries its own uses: lines that the runner re-resolves at execution time regardless of how the outer action was pinned. In a formula those become depends_on entries plus an inreplace at build time. For a composite that internally calls actions/cache@v4:

depends_on "actions-cache"

def install inreplace "action.yml", "uses: actions/cache@v4", "uses: ./.brew-actions/actions-cache" prefix.install Dir.children(".") end

The resulting bottle has no floating refs left in it, brew deps --tree prints the transitive graph that no runner command exposes today, and the tap’s git log records which actions-cache revision the composite was built against. Moving that pin requires a reviewed PR; an action author cannot change it with git tag -f in someone else’s repository. Every incident in the weakest-link post would have required a reviewed change to that index before reaching downstream users, where an npm-style per-project lockfile would only have reduced the number of downstream repositories exposed. A workflow that pins @v4 today has already delegated the version decision to whoever can push a tag to the action repo, and a tap moves that delegation to a reviewer instead. It also matches Homebrew’s rolling-release design, where Brewfile.lock.json was removed in November 2024 and per-project pinning is currently out of scope. I’d like to see the lockfile come back this year, and until it does a workflow that needs stricter reproducibility than the tap’s HEAD can pin the tap itself to a commit. An audit_formula extension for the tap would run zizmor over the extracted action.yml and reject anything that trips dangerous-triggers or template-injection, and reject composites whose internal uses: lines aren’t fully covered by depends_on. The Marketplace’s “verified creator” badge checks the publisher’s identity and nothing about the action’s contents, so a static-analysis gate at index time would be new. Bottles built from the tap are attested by the tap’s CI the same way homebrew-core bottles are. Each formula’s url points at a GitHub repository, which is the input brew vulns already keys OSV lookups on, so an advisory against actions/download-artifact surfaces through the same path as one against openssl. Getting the runner to use it The runner has three ActionSourceType values in ActionStepDefinitionReference.cs (repository, container registry, script) and none of them is “an installed package on disk”, so consuming a Homebrew-installed action means picking one of three integration points at increasing cost. The runner accepts uses: ./path/to/action relative to $GITHUB_WORKSPACE. The prototype tap at andrew/homebrew-actions packages actions/checkout, actions/cache, pre-commit/action and actions/first-interaction. Its setup action runs brew bundle --file .github/Actionfile and copies each keg into ./.brew-actions/, which is where the formula’s inreplace above pointed the composite’s dependency. The Actionfile is a normal Brewfile:

tap "andrew/actions" brew "andrew/actions/pre-commit-action"

steps:

  • uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
  • uses: andrew/homebrew-actions@7def8ee0f83dbb7850e9029c9e0e6ccbafdd209e
  • uses: ./.brew-actions/pre-commit-action

The four formulae pass brew audit, install and test on hosted macOS and Ubuntu runners, and the integration job runs the copied pre-commit/action composite through to its rewritten actions/cache step. It still costs one round-trip to fetch the setup action itself the old way, and checkout stays on a plain SHA pin because it runs before the workspace has anything in it to uses: ./ from. Because ./ is anchored at $GITHUB_WORKSPACE, the setup action has to copy each keg there and checkout has to run first. Runner 2.336.0 added a $/ prefix that anchors at the repository containing the defining file, resolved at the running commit: in a workflow $/ is readable before any step has run, and it’s also valid for reusable workflows (uses: $/.github/workflows/foo.yml), which ./ never supported. gh-actions-lock rewrites existing ./ references to $/ by default and treats the result as inherently pinned, so no lockfile entry is generated for it. Inside a composite loaded via uses: ./path, though, $/ still resolves against the workflow’s repository rather than the copied directory: an earlier iteration of the prototype rewrote the composite’s uses: to $/../actions-cache and the runner attempted to fetch andrew/homebrew-actions/../actions-cache@. So the setup step can’t use $/ to point at $(brew --prefix)/opt, and the .brew-actions destination has to be baked into the formula’s inreplace. On self-hosted runners, ActionManager.cs reads ACTIONS_RUNNER_ACTION_ARCHIVE_CACHE and, if _/.tar.gz exists there, skips the download. A brew bundle on the runner host could populate that directory from the tap. GitHub’s server-side resolver has already chosen the SHA used as the cache key, so this only controls where its bytes come from. It provides an offline mirror but cannot override @v4 resolution. A fourth ActionSourceType could read a formula’s JSON from formulae.brew.sh (or any tap’s API endpoint), verify the bottle attestation, and extract to _actions/. Hosted runners resolve refs to tarballs through the server-side ResolveActionsDownloadInfoAsync call, so a client-side patch would affect self-hosted runners and compatible forks such as act and Forgejo’s runner, with no GitHub backend changes. $/ covers the same-repo case. The setup-step option would also need a similar anchor rooted in a runner-side directory outside any repository. Reusable workflows referenced across repositories (uses: org/repo/.github/workflows/foo.yml@ref) go through a different loader and have no local-path form even with $/, so the setup step cannot load them. They require the runner patch. Docker actions already resolve through a container registry and get whatever pinning the image reference carries. Built in GitHub could integrate the tap into its resolver and leave uses: actions/checkout@v4 unchanged. An organisation or repository setting alongside the existing action allowlists would name the index the resolver consults, and that index would map actions/checkout to a bottle manifest digest instead of a git ref. The runner would pull the layer from ghcr.io, verify the attestation against the tap’s CI identity, and extract to _actions/. Because a composite’s internal refs were rewritten at bottling time, the index response could carry the resolved dependency closure, making the whole transitive tree one index query plus N content-addressed blob fetches. Re-running last week’s job against an unchanged tap commit would produce identical bytes. Switching an organisation from GitHub’s default index to a community tap or an internal one with stricter audit rules would be a settings change, roughly the choice apt users make between Debian stable and a private mirror. An alternative to a settings toggle is package URLs in the uses: line itself (pkg:brew/actions-setup-python, or pkg:oci/...@sha256:... for a direct digest pin), with org policy allowlisting which types and namespaces are permitted. Either way Homebrew’s role is producing one index in the formulae.brew.sh JSON schema, and once the declarative-install work above lands the tap and the index are the same JSON, so any other curator could produce a compatible one without going near Homebrew’s Ruby. Prototype I generated draft formulae for the 70 actions in ecosyste.ms’ current critical set. The pinned sources are 55 JavaScript actions, nine composites and six Docker actions; the JavaScript group is 30 Node 24, 19 Node 20 and six still on Node 12, and all 71 declared pre, main and post entrypoints were present in the archives. Seven of the composites declare external actions, giving seven dependency edges into five repositories, four of which are already in the 70. The two Gradle compatibility actions both depend on subdirectories of gradle/actions, so closing the first-level graph takes one extra formula for 71 in all. Running zizmor 1.28.0 over the extracted action.yml files, as the audit extension above would, reported 61 findings across seven of the 70. 45 are high-severity, high-confidence findings in five actions: 40 template-injection and five unpinned-uses. Five of the six Docker actions also reference their image or Dockerfile base image by tag rather than digest. The generator hit a few ecosyste.ms data issues on the way (two conda-forge packages whose latest release is recorded as master with codeload URLs that now 404 though the stored commit SHAs still fetch, and conda-forge/webservices-dispatch-action classified as composite when the pinned source is a Docker action), and one action, Platane/snk, has no license file for brew audit to accept. The parser, formula emitter and dependency rewrite are in bin/generate-formulae and stayed short because the community lockfile tools already do the same action.yml walk. Getting from the generated drafts to a usable tap needs the audit_formula hook wrapping zizmor and the depends_on coverage check, plus a Windows path for the setup step, which can’t run brew and would have to pull the bottles as plain OCI blobs instead. Gitea’s act_runner and Forgejo’s runner implement the same uses: semantics with no closed server-side resolution call, so the setup-step path works on them today and either of the built-in forms above could land there without a GitHub backend change. Codeberg, Forgejo and Gitea each already maintain an actions org (codeberg.org/actions, code.forgejo.org/actions, gitea.com/actions) that mirrors a hand-picked subset of upstream actions so their users’ workflows resolve without touching github.com. Those orgs are the curated index a tap would produce, maintained by hand, and the Forgejo maintainers have been vocal about wanting something better than inheriting GitHub’s resolution model.

Relative velocity and closing speed

In Physics simulations or game engines it’s sometimes useful to\ndetermine the speed with which two objects are approaching each other.\nThis post will discuss the concept of closing speed, which is the\nnormal component of the relative velocity of two objects.\nRelative velocity and its components\nSuppose we have objects A and B [1] with velocity vectors\n\\vec{V_A} and \\vec{V_B}. The relative velocity of B\nw.r.t. A is:\n\\[\\vec{V}_{B|A}=\\vec{V}B-\\vec{V}A\\]\nPut differently, it’s the velocity of B in A’s frame of reference.\nThis relative velocity is a vector, and we can split it into orthogonal\ncomponents. Obviously, the nature of such a split depends on the basis\nwe want to use. We could look at the vector’s x an y components (we’ll\nbe using - two dimensional space, but everything\nhere applies to 3D as well), but for this post we’re interested in\nsomething slightly different:\nWe draw a line connecting the two objects. The component of\n\\vec{V}{B|A} in the direction of this line is called the\nnormal component of relative velocity, while the component\nperpendicular to this direction is called the tangential component.\nComputing the normal component\nHow do we find the component of a vector in the direction of a specific\nline? By using a vector\nprojection!.\nWe’ll represent the line by a vector, and find the projection of\n\\vec{V}{B|A} onto this vector.\nThe positions of A and B can also be seen as vectors: \\vec{P}_A\nand \\vec{P}_B. The line connecting them can then be expressed as\nthe vector \\vec{P}_B-\\vec{P}_A:\nAll we need from this position difference vector is its direction, not\nits magnitude, however [2]. So we’ll use the unit vector of\n\\vec{P}_B-\\vec{P}_A, denoted as:\n\\[\\widehat{P}=\\frac{\\vec{P}_B-\\vec{P}_A}{|\\vec{P}B-\\vec{P}A|}\\]\nFinally, to find the projection of \\vec{V}{B|A} onto\n\\widehat{P}, we compute [3]:\n\\[S_c=\\vec{V}{B|A}\\cdot\\widehat{P}=(\\vec{V}_B-\\vec{V}_A)\\cdot\\widehat{P}\\]\nWhere the multiplication operator between the vectors is the dot\nproduct. Note that the result of the dot product is a scalar;\ntherefore, the quantity S_c is called the closing speed - it\nexpresses the rate at which the relative distance of the two objects is\nchanging. If it’s positive, the objects are drifting farther apart; if\nit’s negative, the objects are getting closer together. Therefore the\nterm \"closing speed\" may be slightly confusing; alternatively, this has\nbeen called a \"signed separation speed\", or \"normal relative speed\" [4].\nThe signs in these calculations can be tricky to get right, so we have\nto be very careful. Let’s see a few examples that will help us make\nthese computations more concrete.\nExamples\nTo build up some intuition and get some practice with the equations,\nwe’ll review the following examples:\nExample I: We’ll start by computing the relative position unit\nvector \\widehat{P}:\n\\[\\widehat{P}=\\frac{\\vec{P}_B-\\vec{P}_A}{|\\vec{P}_B-\\vec{P}_A|}=\\frac{\\langle 4,0\\rangle}{|\\langle 4,0 \\rangle|}=\\langle1,0\\rangle\\]\nThen, the closing speed is:\n\\[S_c=(\\vec{V}_B-\\vec{V}_A)\\cdot\\widehat{P}=\\langle -3,0\\rangle\\cdot\\langle1,0\\rangle=-3\\]\nBased on our convention, the negative sign of S_c means that the\nobjects are approaching each other. Due to the simple nature of the\nexample, this result is easy to verify, as it can be immediately guessed\njust by looking at the diagram.\nExample II: Here \\widehat{P} is the same as in the previous\nexample. The closing speed is:\n\\[S_c=(\\vec{V}_B-\\vec{V}_A)\\cdot\\widehat{P}=\\langle 3,0\\rangle\\cdot\\langle1,0\\rangle=3\\]\nSame magnitude, but different sign from before, because the objects are\nmoving farther apart.\nExample III This example is to demonstrate that we get consistent\nresults even if B is to the left of A. Here the relative position unit\nvector is:\n\\[\\widehat{P}=\\frac{\\vec{P}_B-\\vec{P}_A}{|\\vec{P}_B-\\vec{P}_A|}=\\frac{\\langle -2,0\\rangle}{|\\langle -2,0 \\rangle|}=\\langle-1,0\\rangle\\]\nAnd the closing speed:\n\\[S_c=(\\vec{V}_B-\\vec{V}_A)\\cdot\\widehat{P}=\\langle 3,0\\rangle\\cdot\\langle -1,0\\rangle=-3\\]\nWhich is the same as in example I, as expected. The direction of\n\\widehat{P} flipped, but so did the direction of the relative\nvelocity vector, so the result has the same sign.\nExample IV: Finally, an example showing more arbitrary positions and\nvelocities.\n\\[\\widehat{P}=\\frac{\\vec{P}_B-\\vec{P}_A}{|\\vec{P}_B-\\vec{P}_A|}=\\frac{\\langle 3,4\\rangle}{|\\langle 3,4 \\rangle|}=\\langle0.6,0.8\\rangle\\]\nThen:\n\\[S_c=(\\vec{V}_B-\\vec{V}_A)\\cdot\\widehat{P}=\\langle -3,-6\\rangle\\cdot\\langle 0.6,0.8\\rangle=-6.6\\]\nThis example is a good opportunity to demonstrate something important\nabout S_c: it’s time-dependent, because positions change with\ntime. Here, -6.6 is the closing speed at the exact moment when A’s and\nB’s positions and velocities are as stated in the example. In the next\ntime step, the position of A will be \\langle2,5\\rangle and the\nposition of B will be \\langle2,3\\rangle, while their velocities\nremain the same. The S_c then will be quite different. This is a\ngood segue to the next topic - which is a more physical view of closing\nspeed.\nClosing speed as a function of time\nThe computation shown so far represents a static view of the world;\nperhaps the right word to use is instantaneous. Given the positions\nand velocities at a given moment, what is the closing speed between the\nobjects at that exact moment?\nBut there’s no reason to not generalize this using a more standard\nphysical interpretation of velocity.\nFirst, let’s state the position vectors of A and B as a function of\ntime: \\vec{P}_A(t) and \\vec{P}_B(t). The relative\nposition vector between the objects is also a function of time:\n\\[\\vec{R}(t)=\\vec{P}_B(t)-\\vec{P}_A(t)\\]\nNow we’ll define the scalar distance as the magnitude of this vector:\n\\[r(t)=|\\vec{R}(t)|=|\\vec{P}_B(t)-\\vec{P}_A(t)|\\]\nWe’re interested in \\frac{dr(t)}{dt} - the change in this\ndistance over time. Let’s start by breaking R(t) down to its\nconstituents:\n\\[\\begin{aligned}\n \\vec{R}(t)&=\\langle x(t),y(t)\\rangle \\\\\n r(t)&=\\sqrt{x(t)^2+y(t)^2}\n\\end{aligned}\\]\nBy the chain rule [5]:\n\\[\\begin{aligned}\n \\frac{dr(t)}{dt}&=\\frac{\\frac{d}{dt}(x(t)^2+y(t)^2)}{2\\sqrt{x(t)^2+y(t)^2}}\\\\\n &=\\frac{2x(t)x'(t)+2y(t)y'(t)}{2\\sqrt{x(t)^2+y(t)^2}}\n =\\frac{x(t)x'(t)+y(t)y'(t)}{\\sqrt{x(t)^2+y(t)^2}}\n\\end{aligned}\\]\nSwitching back to the vector representation: since\n\\vec{R}(t)=\\langle x(t),y(t)\\rangle, the numerator of the\nfraction above is then a dot product between \\vec{R}(t) and\n\\vec{R}'(t), we can write this as:\n\\[\\frac{dr(t)}{dt}=\\frac{\\vec{R}(t)\\cdot\\vec{R}'(t)}{|\\vec{R}(t)|}=\\hat{R}(t)\\cdot\\vec{R}'(t)\\]\nBut \\hat{R}(t) is precisely \\hat{P} from the earlier\nsection, as a function of time. Moreover:\n\\[\\vec{R}'(t)=\\vec{P}'_B(t)-\\vec{P}'_A(t)=\\vec{V}_B(t)-\\vec{V}_A(t)\\]\nBecause velocity is the time derivative of position. Therefore, we end\nup with the same equation, just as a function of time:\n\\[\\frac{dr(t)}{dt}=\\hat{P}(t)\\cdot(\\vec{V}_B(t)-\\vec{V}_A(t))\\]\nThis formulation is more precise because it makes it very obvious that\nall the quantities we’re dealing with are time dependent.\n\n\n[1]Throughout this post, we assume our objects are sufficiently far\napart that they can be treated as points (or particles) without\nany shape, area or volume.\n\n\n[2]The velocity components should be the same regardless of how far\napart the two objects are.\n\n\n[3]In the standard projection formula we’d also divide by the magnitude\nof \\widehat{P}, but in our case it’s a unit vector anyway.\n\n\n[4]In some online sources you may see the closing speed described as\nclosing velocity because it has a direction. IMHO this is the wrong\nframing. Scalars can be signed! The closing speed is certainly a\nscalar, not a vector.\n\n\n[5]The notation x'(t) means \\frac{dx(t)}{dt}

TerminalWidget 1.0

New app from Brett Terpstra: TerminalWidget lets you send output from commands, scripts, APIs, and Shortcuts directly to widgets across macOS, iOS, and iPadOS with rich formatting, progress bars, sparklines, and image support. It is available as a universal app on the App Store for $19.99. I don’t know what I’m going to use this for, but I know I want to use it.  ★

[Sponsor] MCP vs. REST: The Right Way to Connect Agents to Your API

REST serves the developers building against your API. MCP serves the agents now trying to use it. Most teams treat these as competing standards and have to pick one. They’re not rivals, they’re layers: most MCP servers just call REST internally to do the real work. The best ones don’t convert every endpoint into a tool, they design around what the agent’s trying to accomplish. Shipping that server also means shipping OAuth 2.1 with scoped tokens. WorkOS AuthKit already speaks that spec, so you skip building an auth provider on top. Read the breakdown →  ★

John Ternus Has Rehired Former Hardware VP Laura Legros

Juli Clover, MacRumors: Incoming Apple CEO John Ternus is rehiring Laura Legros, a former vice president of hardware engineering who retired from Apple in 2022, reports Bloomberg. Legros previously managed product delivery, development schedules, and coordination across engineering teams. Under Ternus, she will work across different parts of the company, and report directly to him. According to Bloomberg, Legros was one of Ternus’ most trusted deputies before she retired. She has presented at past Apple events, introducing the 2018 MacBook Air and the 2020 iPad Air. The 2018 introduction of the first retina MacBook Air was an interesting event. I noted at the time that it was conspicuous how seldom Apple mentioned “Intel”, despite the fact that all that products introduced ran on Intel chips. Then you look at the specs of that MacBook Air compared to the then-current iPad Pros and you can see why Apple, privately, was seething.  ★

The Information on Apple’s Unusual Use of iCloud for Confidential Work

Aaron “Homeboy” Tilley, reporting for The Information (paywalled without gift links, alas, but MacRumors has a summary): When new employees join Apple, the company often issues them an iPhone and Mac and pays for an iCloud account with a large amount of online storage capacity. Crucially, during the onboarding process, Apple encourages new hires to use their preexisting personal Apple IDs with this iCloud account, through which their co-workers can share internal Apple documents and other files with them. There’s a practical reason for Apple’s policy. Users of iPhones can only log into a single primary Apple ID that unlocks all iCloud capabilities at a time. Apple employees who want to maintain separate work and personal Apple IDs need to carry two iPhones with them. As a result, most Apple employees opt to use their personal Apple IDs to access their iCloud accounts, former employees said. When employees leave Apple, the company revokes access to a dedicated iCloud directory for Apple work files, as well as an authentication system for logging into other internal services, such as Slack. But former employees say the company doesn’t do a thorough job during the offboarding process of looking for confidential files that have slipped through the cracks. Because those former employees typically continue to use their personal Apple IDs with their iCloud accounts, any Apple documents stored outside workplace directories remain available to them. If you use your personal Apple ID, you get a magic “Apple Work” folder in iCloud Drive. When you leave Apple, that “Apple Work” folder disappears. But any other files or folders that were shared with you that were outside that magic folder are still in your iCloud Drive, because it’s still your personal iCloud account. Another factor that plays into this, I think, but which Tilley doesn’t address, is that your Apple ID is not an email address. Your Apple ID is an account that has one or more email addresses associated with it. Let’s say your personal iCloud account has two email addresses associated with it: example@icloud.com and example@gmail.com. Then you take a job at Apple and get the address example@apple.com. When you leave Apple, you lose access to the @apple.com address. But anything shared with your Apple ID through iCloud is still shared with you. You still have the same Apple ID account, even though you no longer have an employee @apple.com email account. Overall, this is a humane way of dealing with digital identity. Your Apple ID account is you, the person, not “example@icloud.com”, one specific unique email address. And you, the person, may well have multiple email addresses — all of which can be associated with your one Apple ID account. That makes Apple IDs more nuanced and complicated than a simple mapping of one email address = one account. And it obviously makes access restrictions more complicated. Let’s say you delete your Gmail account. Now you can’t access your old example@gmail.com email address. But your iCloud access to items shared with your Apple ID still works, even for items that were sent to your now-deleted @gmail.com address. That’s just now how “work stuff” is accessed at most companies. Tilley’s report at The Information is presented as being potentially relevant to Apple’s trade secret lawsuit against OpenAI, but Apple, in a statement to The Information, says it is not: In a statement, Apple said: “This case is about OpenAI employees wrongfully taking Apple’s secret and confidential information regarding our unreleased technologies, processes, and products. Nothing in the filing relates to documents shared by, or stored in, iCloud.” The company said it doesn’t pursue legal claims against former employees who accidentally hold on to Apple documents in their personal iCloud accounts.  ★

Om Malik’s Final Essay: ‘The Myth, the Mythos and the Man’

Om published this on Monday June 7 — the day of the WWDC keynote. He sent me a note about it, that is too personal to share in full. He described it as his “last shot” — “In case I don’t make it”. He didn’t make it. I didn’t read it right away because I was busy with WWDC. Then, after he died, I didn’t read it because I couldn’t bring myself to. I did, finally, today. It’s so good. Truly insightful. A taste: Augustus had the Senate and the priests. Dario had the Oval Office and the Vatican. The structure is the same. Two thousand years apart. Plato would recognize this immediately. He spent his career distinguishing the philosopher who seeks truth from the sophist who manufactures persuasion. The sophist is not lying exactly. The sophist is selecting, sequencing, and presenting in ways that produce belief without requiring the audience to do the work. Mythos, for Plato, was the domain of poets and myth-makers. Useful for educating the young, dangerous when deployed as a substitute for rigorous argument among adults. He would look at Anthropic’s naming strategy and see sophistry wearing philosophical clothes. If you haven’t already, set aside some time and give it a read.  ★