Anchored Log Reconstruction, principle 4
Key finding
Start from a state the log can prove and work back to a cause, ruling out each alternative with captured data. On macOS a successful Touch ID match does not mean the machine unlocked. The lock state lives on three layers that do not always agree, so name the layer you report, and remember that an empty search only tells you what your search string matched.
The question you will be asked
At some point someone asks how you know. Not whether the log contains fingerprint lines. How you know the machine was unlocked, by that method, at that moment.
The tempting way to answer is to search for what you expect. You believe the machine was unlocked with a fingerprint, you search for fingerprint lines, you find them, and you put them in the report. That approach nearly always produces a hit, which is exactly what makes it worthless. A modern system writes so much that you can find support for almost any account you bring to it. Finding what you were looking for is not a finding.
Principle 4 reverses the direction. You start at a state the log can prove, and you work backwards towards a cause.
This is not the same question as post #25. That one was about two lines close together and whether one caused the other. This one is about where you start.
Why backwards is not automatically safer
Reasoning from an effect to a cause is abduction. It is only worth as much as the alternatives you actually considered. Pick one line, call it the cause, stop, and you have not reconstructed anything. You have written your own assumption down in the vocabulary of the log, which reads convincingly until someone asks you to defend it.
So the principle carries a rule inside it. Every step backwards gets a competing explanation and a ground for ruling that explanation out, and the ground has to come from data you captured. Not from what you know about how the system works. Where you cannot rule an alternative out, you say so in the report and you stop there.
That last sentence is the part that holds up under questioning. An analyst who has written down where he stopped, and why, is in a far better position than one who reasoned all the way to the front door.
Which lock state do you mean
Everything below comes from a run on a MacBook Pro, Mac16,8, macOS 26.6.2 build 25G83, FileVault on, one account, one enrolled fingerprint. The logbook ran on a second machine so the machine under test would not log the logbook. On this model the Touch ID sensor sits in the power button, so waking with that button is also touching the sensor. Every wake in the run used a keyboard key, except in the block where the button itself was under test.
The first thing that run made clear is that this machine does not have one lock state. It has at least three, on three layers, and they do not always agree.
The keys themselves. The kernel reports that the encryption keys became available and that the volume became readable. This is the deepest layer and the one to anchor on where it is available, because the kernel writes it regardless of which process happened to be watching.
The session. loginwindow decides whether the screen comes down, and a separate process reports that transition.
What the user saw. The notification layer reports the lock screen going away.
Most of the time these move together. Not always. In one repetition the keys became available with nothing happening at the session layer. In another the session moved and the keys never did.
That means “the machine was unlocked” is not a complete statement. Confirming that the keys became available is a different claim from confirming that the lock screen came down, and reporting one while the other says something else is where a reconstruction quietly goes wrong. Name the layer in the report.
There is a harder consequence, and it took me a second pass to find it. The deepest layer is not always there. After a cold start the machine records the transition on the layer above it and the kernel says nothing at all. So the rule cannot be “anchor on the kernel”. It has to be “anchor as deep as this system actually wrote for this event, and record which layer that was”. An anchor that only holds for the ordinary case is not an anchor.
A second thing follows. Two processes writing about the same notification are not two witnesses. In this run two user-space processes reported the keybag transition, and they reported it identically, every time, in the same order. That is one message relayed twice. When you say the end state is confirmed independently, check that the confirmation came from separate observation and not from a shared source.
A successful match is not an unlock
This is the finding I would keep if I could keep only one, because it is the one an opposing expert will reach for.
The fingerprint sensor and the Secure Enclave write a line when they recognise a print. In the Touch ID block that line appears far more often than the machine actually changed state. It also appears in the control block, where I rested the enrolled finger on the sensor while the machine was already unlocked and in use. Successful match, every time, and nothing changed.
The match line says what the sensor concluded about a finger. It says nothing about anything happening as a result. Reasoning from a match to an unlock is the abductive error above, and in this run it would have been wrong most of the times you tried it.
One repetition shows how that fails in practice. I locked the machine and woke it again almost immediately, faster than anywhere else in the run. The keys never locked, so there was nothing to unlock. The session layer cycled anyway. From the outside that repetition was indistinguishable from the others: same actions, same screen, desktop at the end. The log holds successful matches for it. An analyst reasoning forward from “finger on the sensor, then the desktop” would have called it an unlock, and nothing in the biometric lines would have contradicted him. Only the missing endpoint does, and only if he thought to look at that layer.
Reading the method off the state
Post #26 documented that this machine uses a separate keybag state for biometric unlocks. The run confirms it and adds something more useful.
Once the machine enters that biometric state, it stays there. It does not settle back into the ordinary unlocked state afterwards. It goes from the biometric state straight into locking when the session ends.
That has a practical consequence. The authentication method is not only readable at the moment of unlocking. It is readable from the state the session was in, including at the point where the machine locks again. If the unlock moment itself falls outside your window, or was never written, the exit still tells you how that session began.
The kernel lines do not make this distinction. They are identical after a fingerprint and after a password. So the layer you choose determines what you can say: on one layer the method is handed to you, on the other you have to reconstruct it from the chain. Neither layer is wrong. They answer different questions, and the report has to state which question was asked.
A line that says password, and no password
In the block where I only used the fingerprint, and typed nothing, the log is full of lines reporting that a password was verified and that an authentication failed.
They run through the whole block, and no password was entered anywhere in it. Whatever produces them, it is not a user typing. What they do record is not established here and is not claimed.
An analyst who searches for “password”, or for “failed”, will report a series of password events in a block where nobody touched the keyboard. That is not a hypothetical. It is the kind of error that survives review, because the line contains the word that the reader was looking for and appears to carry its own conclusion.
The genuine entries are distinguishable, but not by the word. They carry a different result code and a different domain than the internal ones. Real failed attempts, where I deliberately typed the wrong password, look different again.
The rule that comes out of this belongs to the method rather than to macOS: a field name is not a definition. Before a line is used as an indicator, it has to be checked in a block where the thing it names did not happen.
Where I stopped, and where I was wrong to stop
The cold start is where this principle earns its place, and it is where I nearly got it wrong myself.
On Apple Silicon with FileVault, the first authentication after power-on happens before the running system exists. The log for that boot begins afterwards. So the password typed at the pre-boot screen is not in the archive, and no amount of working backwards will produce it. The endpoint is provable in the ordinary sense, because the system is running and the desktop is there. The authentication that caused it is not recoverable. The right move is to stop, and to write down that you stopped, rather than reaching back into the previous boot session where the time base is different and the causal link is severed.
All of that holds. What does not hold is the conclusion I drew about the log being silent.
I searched those windows for the transition string I had seen everywhere else in the run, found nothing, and wrote down that there was no keybag transition at a cold start. There is one. The machine writes it a couple of seconds after the account login, on every cold start in the run, in different wording than the one I searched for.
That is the same error as reasoning from the match line, in the opposite direction. A search that comes back empty tells you what the search matched, not what happened. If a state has to exist, and you cannot find the line, the first hypothesis is that you are looking for the wrong string.
There is one more thing in those windows. The kernel does not write its notification there at all. The transition exists only on the layer above it. So on this system the first unlock after a boot is recorded differently from every other unlock, on a shallower layer, by processes rather than by the kernel. An analyst who has settled on the kernel line as his endpoint will find nothing after a cold start and, if he is not careful, will write that the machine was never unlocked.
Ruling out the power button
The competing explanation for a finger on this sensor is that somebody pressed the power button without intending to authenticate. At the match layer the two are indistinguishable, and the run confirms that: a button press and a non-enrolled finger both produce a non-match with nothing to separate them.
The wake line does separate them. Post #26 showed that it names the input device, so a wake by the power button and a wake by the keyboard are on the record as different events. The alternative is excluded by an observation rather than by argument, which is what this principle asks for. Before that line was documented, this was a cell in the table I had to leave empty, and leaving it empty was the correct answer at the time.
What log order does and does not tell you
Within one unlock the kernel writes its notification before the driver and the daemon report the match. The decision had already been taken; the others are reporting afterwards.
Across repetitions of the same physical action, two events swap order. Neither is wrong. Log order records when each process managed to write, not the order in which things happened.
Backward reasoning therefore works on ordering and causal coupling inside one boot session. It does not work on absolute placement, and it does not survive a restart. Treating a sub-second sequence as a causal one repeats the error from #25 at a smaller scale. A proper treatment of the clock is beyond a blog post and belongs in the paper.
The logbook is not the event record
Twice in this run my marks and the system disagreed. My mark for locking the machine sits well after the button press that actually locked it. And in one repetition my logbook shows a single password entry where the log shows a rejected attempt followed by a successful one.
Neither is a defect. The logbook records what the examiner did and observed, and its job is to bound the search window in the archive. Anything that happened between the marks was never going to be in it.
Which is the argument for starting at the endpoint. A state transition carries no mark, because nobody marks a state transition. Only the system writes it down.
Limits
One machine, one build, one account, one enrolled finger. On a system with several accounts, linking the end state to a person needs its own demonstration, because the kernel lines name nobody.
The end-state lines did not appear in the block where I woke the machine without unlocking it, in the block where I touched the sensor while it was already unlocked, or in the locked idle block. That is not a claim that they never occur without a state change. It is a record of which windows were checked and where they were absent, which is what belongs in a report.
The intervals in the logbook are examiner observations. They bound the search window. They are not system latencies and must not be reported as such.
Reproducibility
| Item | Value |
|---|---|
| Model identifier | Mac16,8 |
| Chip | Apple M4 Pro |
| OS | macOS 26.6.2 |
| Build | 25G83, recorded with sw_vers at acquisition |
| FileVault | on |
| User accounts | 1 |
| Enrolled fingerprints | 1 |
| Acquisition | log collect, same day as the run |
| Extraction | log show --archive <path> --style ndjson --info --debug |
| Logbook | separate machine, append-only JSONL, external clock reading at start and end |
| Data | own reference device, no casework data |
--info --debug is not optional. Without both flags the extraction drops the levels that carry most of this.
What I checked, and what came back
Does the sensor report a finger for a print that is not enrolled? Yes, and that line alone does not distinguish it from an enrolled one.
Does it report a finger when the machine is already unlocked? Yes, and a successful match with it, and nothing changes state.
Can you read the authentication method off the kernel end state? No. It is identical after a fingerprint and after a password.
Can you read it off the keybag state? Yes, and that state persists until the machine locks again.
Does an end-state line appear when you wake without unlocking? Not on any of the three layers.
Is a power-button press distinguishable from a deliberate presentation? Not at the match layer. The wake line separates them.
Do the cold starts produce a keybag transition? Yes, but only on the layer above the kernel.
Forward
Two things from this run belong to principle 5 and are held for the next ALR method post. The extraction did not respect the requested end of the window when it crossed a boot boundary, and the way timestamps and hostname are rendered changes across that same boundary. The second is now reproduced several times within this one run.
Retention is driven by how much gets written rather than by how much time passes, which supersedes the formulation in #23. The replacement is worked out per subsystem in next method post.
© 2026 Tim Korver — Thesis Friday. Licensed under CC BY-NC-ND 4.0. Method: Anchored Log Reconstruction (ALR). Commercial or training use requires written permission. See Copyright and Use.

