CODE
CODE = 'drill.drift'
The finding code a drill raises when the store does not reproduce the site.
Proves the store can reproduce what the site holds, on a schedule, without restoring anything.
A backup nobody has restored is a hypothesis. This is what turns it into a measurement: for a bounded sample of subjects, replay what the store says the subject was at the commit where it was last captured, read what the site holds now, and compare. Nothing is written; a drill is a read of both sides.
The comparison is only valid where the site has not moved on. A subject edited after the
commit that was replayed will differ for a legitimate reason, and counting that as a failure would
make every busy site look broken. So a subject whose last capture is older than its current state
is SKIPPED, and the report keeps skipped separate from both pass and fail. A drill that could judge
nothing reports inconclusive rather than pass.
What a drill does not prove. It reads the sample it took, so a fault confined to a subject outside the sample survives it; it compares values rather than replaying a whole restore, so it says nothing about whether writing those values back would succeed; and it cannot see a subject the capture never recorded, which is what the reconciler exists for. What it does prove is that the bytes in the bucket decode, resolve through their delta chains and dictionaries, and reconstruct the value they claim to hold.
$replayer : \Drupal\strata\Restore\Replayer
$subjects : \Drupal\strata\Tree\SubjectIndex
$refs : \Drupal\strata\Tree\RefStore
$commits : \Drupal\strata\Tree\CommitLog
$ledger : \Drupal\strata\Health\HealthLedgerInterface
$index : ?\Drupal\strata\Drill\DrillIndex
$notifier : ?\Drupal\strata\Event\Notifier
__construct(\Drupal\strata\Restore\Replayer $replayer, \Drupal\strata\Tree\SubjectIndex $subjects, \Drupal\strata\Tree\RefStore $refs, \Drupal\strata\Tree\CommitLog $commits, \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager, \Drupal\Core\Config\ConfigFactoryInterface $configFactory, \Drupal\Core\State\StateInterface $state, \Drupal\strata\Health\HealthLedgerInterface $ledger, \Drupal\Component\Datetime\TimeInterface $time, \Psr\Log\LoggerInterface $logger, \Drupal\strata\Drill\DrillIndex|null $index = null, \Drupal\strata\Event\Notifier|null $notifier = null) : mixed
Constructs a runner.
| \Drupal\strata\Restore\Replayer | $replayer | Reconstructs what the store says a subject was. |
| \Drupal\strata\Tree\SubjectIndex | $subjects | Names the subjects and when each was last captured. |
| \Drupal\strata\Tree\RefStore | $refs | Supplies the commit to replay against when none is given. |
| \Drupal\strata\Tree\CommitLog | $commits | Reads when the replayed commit was sealed, which is what the moved-on check compares against. |
| \Drupal\Core\Entity\EntityTypeManagerInterface | $entityTypeManager | Loads the live entities. |
| \Drupal\Core\Config\ConfigFactoryInterface | $configFactory | Loads the live configuration. |
| \Drupal\Core\State\StateInterface | $state | Loads the live state values. |
| \Drupal\strata\Health\HealthLedgerInterface | $ledger | Where drift is recorded. |
| \Drupal\Component\Datetime\TimeInterface | $time | Stamps the report. |
| \Psr\Log\LoggerInterface | $logger | Records the verdict. |
| \Drupal\strata\Drill\DrillIndex|null | $index | Where the run is recorded, or NULL not to record it. |
| \Drupal\strata\Event\Notifier|null | $notifier | Announces the result, or NULL to stay silent. |
run(string|null $target = null, int $sample = 0) : \Drupal\strata\Drill\DrillReport
Runs a drill.
| string|null | $target | Commit to replay against, or NULL for the current head. |
| int | $sample | Subjects to examine, or 0 for the default. A negative value examines every subject. |
What the drill found.
examine(string $subject, string $commit, int $at = 0) : array{string, string}
Compares one subject against what the store says it was.
| string | $subject | Subject path, in the form |
| string | $commit | Commit to replay against. |
| int | $at | Unix microseconds the commit was sealed at, or 0 to read it from the commit. Passed in by a whole-drill run, which resolves it once rather than per subject. |
The verdict constant and a note.
sealedAt(string $commit) : int
When a commit was sealed.
Read from the commit itself rather than from the local index, so a drill still knows the moment on a store whose index has been dropped and not yet rebuilt.
| string | $commit | The commit id. |
Unix microseconds, or 0 when the commit cannot be read.
compare(\Drupal\strata\Restore\ReplayResult $result, array$live) : array{string, string}
Compares a replayed value against the live one.
Only the fields the store claims to know are compared. A field the site has and the capture never recorded is not evidence the store is wrong; it is evidence the capture scope excludes it, which is a different question and the reconciler's.
| \Drupal\strata\Restore\ReplayResult | $result | What the store reconstructed. |
| array |
$live | What the site holds. |
The verdict constant and a note.
live(string $subject) : array<string,mixed>|false|null
The live value of a subject, as a field map.
| string | $subject | Subject path. |
The field map, FALSE when the realm holds values but this one is gone, or NULL when the realm is one a drill cannot read back.
liveEntity(string $name) : array<string,mixed>|false|null
The live field map of an entity named by a subject path.
| string | $name | The part after the realm, in the form |
The field map, FALSE when the entity is gone, or NULL when the path is not readable.
normalize(mixed $value) : string
Reduces a value to something two sides can be compared on.
A stored value has been through JSON, so an integer may come back as a string and an object as an array. Comparing the serialized forms rather than the values themselves makes the drill insensitive to that round trip and sensitive to what actually changed.
| mixed | $value | The value. |
A comparable form.
choose(list$subjects, int $sample) : list<string>
The subjects one drill examines.
Chosen by even stride rather than at random, so two drills of the same store cover different subjects only when the store has changed, and a repeated drill of a failing store reproduces the failure rather than hiding it behind a new sample.
| list |
$subjects | Every subject the index holds. |
| int | $sample | How many to examine, 0 for the default, negative for all. |
The chosen subjects.
refuse(string $reason, float $started, string $target = '') : \Drupal\strata\Drill\DrillReport
A report for a drill that could not start.
| string | $reason | Why it did not run. |
| float | $started | When it was attempted. |
| string | $target | The commit it would have used. |
The refusal.