From ios-forensics
Reconstruct what happened on an iOS device and when — application usage, backgrounds/foregrounds, device lock state, location, cellular context — using knowledgeC.db, routined, PowerLog, CellularUsage, Safari, and related artifacts. Builds evidence-backed timelines.
How this skill is triggered — by the user, by Claude, or both
Slash command
/ios-forensics:activity-reconstructionThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
- Need to answer "what was the user doing at time T?"
Produce a defensible timeline: timestamps, events, sources, confidence — tied directly to DB rows or plist entries.
| Artifact | Source | What you get | Source kind |
|---|---|---|---|
knowledgeC.db | AppDomainGroup-group.com.apple.Preferences/Library/CoreDuet/Knowledge/ | App in focus, device lock, backlight, media playing, location context — the iOS timeline | backup + fs |
InteractionC.db | AppDomainGroup-group.com.apple.coreduet/Library/CoreDuet/People/ | Contact interactions, share-sheet use | backup |
PowerLog (powerlog.PLSQL) | FFS only | Boot / shutdown / app power draw | fs |
CellularUsage.db | WirelessDomain/Library/Databases/CellularUsage.db | SIM / carrier changes | backup |
DataUsage.sqlite | WirelessDomain/Library/Databases/DataUsage.sqlite | Per-process network bytes | backup |
routined | HomeDomain/Library/Caches/com.apple.routined/*.db (backup often sparse; FFS has the full set) | Significant locations, visits | backup + fs |
Safari History.db | HomeDomain/Library/Safari/History.db | URL + visit timestamps | backup |
Photos.sqlite | CameraRollDomain/Media/PhotoData/Photos.sqlite | Photo creation, location, album membership | backup |
Health/healthdb_secure.sqlite | HealthDomain/Health/healthdb_secure.sqlite | Activity samples, heart rate, workouts | backup (encrypted-backup only) |
ios_backup_extract(backup_dir, "AppDomainGroup-group.com.apple.Preferences",
"Library/CoreDuet/Knowledge/knowledgeC.db",
output_dir)
Core tables / streams to query:
/app/inFocus — which app was in focus and for how long/app/activity — app background/foreground events/device/isLocked — lock state transitions/device/isPluggedIn — charging transitions/audio/mediaPlaying — media playback (nowplayingd)/app/usage — rolled-up usage counts/location/visit — visits to significant locationsCanonical query (adjust to the window of interest):
SELECT
ZOBJECT.ZSTREAMNAME AS stream,
ZOBJECT.ZVALUESTRING AS value,
datetime(ZOBJECT.ZSTARTDATE + 978307200, 'unixepoch') AS start,
datetime(ZOBJECT.ZENDDATE + 978307200, 'unixepoch') AS end,
(ZOBJECT.ZENDDATE - ZOBJECT.ZSTARTDATE) AS duration_s
FROM ZOBJECT
WHERE ZOBJECT.ZSTARTDATE + 978307200 BETWEEN :t_start AND :t_end
ORDER BY ZOBJECT.ZSTARTDATE;
Interpretive notes:
/app/inFocus with duration near zero = brief tap / background triggerisLocked=1 = audio-only / headphones / CarPlay scenarioisLocked=1 = someone interacted with notifications without unlockingHistory.db → history_items joined to history_visits gives URL + visit timestampPhotos.sqlite → ZASSET.ZDATECREATED + optional ZADDITIONALASSETATTRIBUTES locationBackup path (sparse): mvt_run_module(source, module="locationd") or extract HomeDomain/Library/Caches/locationd/*.
FFS path (full): mvt_run_module(source, source_kind="fs", module="locationd") plus routined tables (CoreRoutine, RTVisit objects, Cloud.sqlite).
For significant locations on FFS: ios_backup_list path_substring="routined" then query the Cloud.sqlite + Local.sqlite files' ZRTLEARNEDVISIT, ZRTLEARNEDLOCATION. Note the coordinate rounding (~50m) and confidence column.
ios_backup_extract backup_dir "WirelessDomain" "Library/Databases/CellularUsage.db" out
ios_sqlite_query(<CellularUsage.db>, "SELECT ZLABEL, ZICCID, datetime(ZSUBSCRIBERINFOUPDATEDATE+978307200,'unixepoch') FROM ZSUBSCRIBERINFO")
SIM changes tell you: the user swapped carriers, eSIM was provisioned, or someone replaced the SIM — relevant for IMSI-catcher and SIM-swap cases.
PowerLog (powerlog.PLSQL) contains tables like PLProcessMonitorAgent_EventPoint_ProcessExit, PLSleepWakeAgent_Interval_Session, PLAccountingOperator_EventNone_Nodes. Boot and shutdown timestamps close to incident windows frequently matter.
One row per event, ordered. Columns: timestamp, duration, source (table + DB), event, actor (app / daemon / system), confidence (direct = row-backed; derived = inferred).
Merge with timestamps from spyware-hunt (shutdown_log entries, suspicious SMS, datausage onsets, configuration profile installs). The combined timeline is usually what answers the case's fundamental question.
Every iOS SQLite store uses Cocoa time: seconds (sometimes nanoseconds) since 2001-01-01 UTC. Convert with ts + 978307200 for seconds, or ts / 1e9 + 978307200 for nanoseconds, then standard datetime(..., 'unixepoch'). Miss this once and your entire timeline is offset by 31 years; we mention it here because that exact mistake shows up in almost every first-timer report.
Deliver as a timeline table (CSV or markdown). For every row, include a stable pointer to the source (DB name, table, rowid) so anyone can re-derive the claim.
knowledgeC.db durations in minutes when they're seconds/app/inFocus as "user looked at the phone" — could be CarPlay, Apple Watch handoff, or notification-center glanceroutined; the iTunes-backup version has a small subsetnpx claudepluginhub s3cr1z/capabilities --plugin ios-forensicsProvides behavioral guidelines to reduce common LLM coding mistakes, focusing on simplicity, surgical changes, assumption surfacing, and verifiable success criteria.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.