Skip to content

Instantly share code, notes, and snippets.

@louspringer
Created November 13, 2025 19:13
Show Gist options
  • Select an option

  • Save louspringer/4a7ef75e7530e8df21cba970746bb67f to your computer and use it in GitHub Desktop.

Select an option

Save louspringer/4a7ef75e7530e8df21cba970746bb67f to your computer and use it in GitHub Desktop.
macOS removable-volume update incident artifacts

Removable-Volume Update Counterexample (CIA Failure)

Let:

  • V be a removable volume mounted at /Volumes/lemon.
  • B_live denote the deployed Cursor bundle at /Volumes/lemon/cursor/Cursor.app.
  • B_stage denote the staged update bundle cached at ~/Library/Caches/com.todesktop.230313mzl4w4u92.ShipIt/update.VodNX6R/Cursor.app.
  • P_write represent the Files & Folders → Removable Volumes permission required for ShipIt to write to V.

During the 2025-11-13 update attempt, ShipIt executed the following sequence:

  1. Remove B_live from V.
  2. Attempt to copy B_stage from cache to V.
  3. System Policy denied the copy because P_write was not granted.

This yields the following observations:

  • Integrity (I): Integrity requires B_live remain unmodified unless the replacement B_stage is successfully written. Here, B_live was deleted while B_stage never landed. Therefore Integrity(V) is violated.

  • Availability (A): Availability requires that Cursor remain runnable after the update process. Since /Volumes/lemon/cursor/Cursor.app was left empty, Cursor cannot launch, so Availability(V) is false until manual restoration.

  • Confidentiality (C): Confidentiality requires that the bundle not be exposed beyond authorized contexts. Yet the full replacement bundle remains world-readable in ~/Library/Caches/.../update.VodNX6R, so any local user can copy it. Thus Confidentiality(B_stage) fails.

Because at least one of {Integrity, Availability, Confidentiality} is false in this concrete execution, macOS cannot guarantee the CIA triad for removable-volume applications under the current update policy.

@prefix : <https://lou.example.org/ontology/lemon-cursor#> .
@prefix incident: <https://lou.example.org/ontology/incident#> .
@prefix prov: <http://www.w3.org/ns/prov#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
# Vocabulary overview:
# incident:IncidentType — any incident record
# incident:Application — deployed software bundle
# incident:Volume — storage volume
# incident:UpdaterProcess — helper attempting to update
# incident:PermissionFailure — denial of required capability
# incident:ActionPlan — recommended remediation steps
# incident:hasLabel — human-readable name
# incident:startedAt / detectedAt — timestamps (xsd:dateTime)
# incident:evidenceLog — textual evidence entries
# incident:recommendation — remediation bullet
# prov:Entity / prov:used / prov:wasGeneratedBy — provenance links per W3C PROV
# Example SPARQL query to list all recommendations:
# PREFIX incident: <https://lou.example.org/ontology/incident#>
# SELECT ?recommendation WHERE { :RecommendedRemediation incident:recommendation ?recommendation . }
:Incident a incident:IncidentType ;
incident:hasLabel "Cursor auto-update removal failure on removable volume" ;
incident:startedAt "2025-11-13T09:51:20-07:00"^^xsd:dateTime ;
incident:detectedAt "2025-11-13T09:52:51-07:00"^^xsd:dateTime ;
incident:status incident:MissingApplication ;
incident:impact "Cursor.app bundle removed from /Volumes/lemon during ShipIt update and not restored due to sandbox permission denial." ;
incident:rootCause :PermissionConstraint .
:CursorApp a incident:Application ;
incident:bundleIdentifier "com.todesktop.230313mzl4w4u92" ;
incident:bundlePath "/Volumes/lemon/cursor/Cursor.app" ;
incident:version "0.45.x (exact build unknown; retrieved from ShipIt cache)" ;
incident:hasAlias "/Volumes/lemon/cursor alias" .
:LemonVolume a incident:Volume ;
incident:volumeName "lemon" ;
incident:mountPoint "/Volumes/lemon" ;
incident:medium "External SSD" .
:ShipItHelper a incident:UpdaterProcess ;
incident:processName "ShipIt" ;
incident:logPath "~/Library/Caches/com.todesktop.230313mzl4w4u92.ShipIt/ShipIt_stderr.log" ;
incident:requiresPermission incident:FilesAndFoldersRemovableVolumes .
:PermissionConstraint a incident:PermissionFailure ;
incident:denyingAuthority "System Policy" ;
incident:deniedCapability "file-write-create" ;
incident:errorCode "NSCocoaErrorDomain Code=513" ;
incident:logEvidence [
incident:source "log show --style syslog --predicate 'eventMessage CONTAINS[c] \"/Volumes/lemon/cursor/Cursor.app\"'" ;
incident:excerpt "System Policy: ShipIt deny(1) file-write-create /Volumes/lemon/cursor/Cursor.app"
] ;
incident:logEvidence [
incident:source "ShipIt_stderr.log" ;
incident:excerpt "Couldn't move bundle contents ... because you don't have permission to access 'cursor'."
] ;
incident:affects :ShipItHelper .
:UpdateAttempt a incident:UpdateProcess ;
prov:used :CursorApp ;
prov:wasAssociatedWith :ShipItHelper ;
incident:targetVolume :LemonVolume ;
incident:stagedBundle "~/Library/Caches/com.todesktop.230313mzl4w4u92.ShipIt/update.VodNX6R/Cursor.app" ;
incident:step [
incident:action "Move original bundle off target" ;
incident:timestamp "2025-11-13T09:52:45-07:00"^^xsd:dateTime
] ;
incident:step [
incident:action "Attempted copy of new bundle back to /Volumes/lemon/cursor/Cursor.app" ;
incident:timestamp "2025-11-13T09:52:50-07:00"^^xsd:dateTime ;
incident:result "Denied by System Policy"
] ;
incident:result incident:BundleMissing .
:RecommendedRemediation a incident:ActionPlan ;
incident:recommendation "Grant ShipIt/Cursor Full Disk Access or Files and Folders › Removable Volumes before running updates." ;
incident:recommendation "Alternatively relocate Cursor.app to /Applications to avoid removable-volume policy enforcement." ;
incident:recommendation "If restoring from Time Machine, ensure Terminal has Full Disk Access so tmutil can mount backups." ;
incident:recommendation "Keep Feedback Assistant (system copy at /System/Library/CoreServices/Applications/Feedback Assistant.app) readily accessible so critical crash workflows do not hide diagnostic tooling." ;
incident:recommendation "Allow Feedback Assistant to expose a public automation API so incident data can be submitted programmatically instead of retyped into a static form." ;
incident:recommendation "Allow Feedback Assistant to be launched and scripted via osascript without requiring hidden triggers; see osascript activate command executed during investigation." ;
incident:recommendation "Document a reliable escalation path; current process lacks convergence so issue reporting stalls when APIs and tooling are inaccessible." ;
incident:recommendation "Require updaters to confirm replacement bundles are in place before deleting working binaries (violated here, causing silent removal of Cursor.app)." ;
incident:recommendation "Surface real-time alerts when System Policy denies an updater so data loss is not left to human luck." ;
incident:recommendation "Provide deterministic remediation steps for external-volume installs instead of forcing users to guess which permissions are missing." ;
incident:recommendation "Publish entitlement guidance specific to removable volumes so vendors know how to request Files & Folders access without trial-and-error." ;
incident:recommendation "Expose ShipIt/auto-update status in UI so users know when bundles are staged in caches and can restore them." ;
incident:recommendation "Offer a rollback mechanism when updates fail midstream, rather than leaving the target path empty." ;
incident:recommendation "Support machine-readable incident submissions (e.g., accept Turtle/prov files) to avoid retyping precise diagnostics; a structured model is required to capture incidents like this accurately." ;
incident:recommendation "Include Feedback Assistant in /Applications by default and document that it can be launched via osascript for automation." ;
incident:recommendation "Allow Terminal/tmutil to prompt for Full Disk Access automatically so backup inspection is not blocked by hidden settings." ;
incident:recommendation "Acknowledge that current protections destroyed deployed data, contradicting Apple’s custodianship goals; update policy accordingly." ;
incident:recommendation "Ensure developer workflows on non-default locations (external SSDs) are first-class citizens rather than edge cases." ;
incident:recommendation "Address CIA triad regressions: integrity violated when updater deletes binaries, availability lost when app vanishes, and confidentiality risked by leaving full bundle copies in world-readable caches." ;
incident:recommendation "Reinstate the invariant 'never delete live software until the replacement is verified'—a lesson repeated throughout computing history but still missing here." ;
incident:recommendation "Publish a decision log whenever System Policy blocks critical operations so stakeholders can audit why availability was sacrificed." ;
incident:recommendation "Provide a deterministic export of provenance/ontologies from Feedback Assistant so structured reports remain intact." ;
incident:recommendation "Automatically snapshot removable-volume apps before attempting updates, guaranteeing rollback regardless of user expertise." ;
incident:recommendation "Warn when Time Machine silently excludes external volumes and provide one-click inclusion so backups actually cover removable installs." ;
incident:recommendation "Name cache folders and helper processes clearly (not random strings like update.VodNX6R or com.todesktop...) so users don't mistake them for malware." .
:Incident a prov:Entity ;
prov:wasGeneratedBy :UpdateAttempt ;
incident:hasRemediation :RecommendedRemediation ;
incident:involvesVolume :LemonVolume ;
incident:involvesApplication :CursorApp ;
incident:evidenceLog "~/Library/Caches/com.todesktop.230313mzl4w4u92.ShipIt/ShipIt_stderr.log" ;
incident:evidenceLog "/System/Library/CoreServices/Applications/Feedback Assistant.app (present but hidden unless triggered by crashes)" ;
incident:evidenceLog "osascript activation command issued to surface Feedback Assistant manually" ;
incident:evidenceLog "No public API or automation mechanism available even with explicit user authorization, blocking structured submissions" ;
incident:evidenceLog "Updater deleted working Cursor.app before ensuring replacement existed, violating custodianship" ;
incident:evidenceLog "System Policy denial surfaced only in logs; no user-facing alert occurred" ;
incident:evidenceLog "tmutil commands refused to run without Full Disk Access, preventing timely verification" ;
incident:evidenceLog "ShipIt cache consumes 566 MB at ~/Library/Caches/com.todesktop.230313mzl4w4u92.ShipIt/update.VodNX6R, exposing unprotected app payload" ;
incident:evidenceLog "/System/Library/CoreServices/Applications/Feedback Assistant.app owned by root:wheel and hidden from standard Applications view" ;
incident:evidenceLog "Structured model (ontology) chosen intentionally; Apple provides no alternative path to encode multi-dimensional incidents" ;
incident:evidenceLog "Obfuscated cache folder names (e.g., update.VodNX6R, com.todesktop...ShipIt) mimic malware naming patterns and cause repeated false infection alarms every time they appear" ;
incident:evidenceLog "Time Machine stopped backing up external volumes without warning; `tmutil latestbackup` shows last snapshot at 2025-11-13-110108 missing /Volumes/lemon unless user adds it manually" ;
incident:observedBy "Codex CLI session 2025-11-13" .
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment