◇ OpenCyber Academy
Rapid course · Lesson 8 · English

A source hold is a separate lifecycle

Open, free learning for anyone who wants to protect people and technology. No account is required to read this text or its worked answers.

Lesson 08 — A source hold is a separate lifecycle

Week 2, day 3. Work through the teaching and the worked checkpoint before attempting the assigned exercise(s). Compare your artifact with the final worked result only afterward.

2.8a Verify a source preservation hold separately from a retained copy

2.8a.1 A request to preserve data is not the preservation itself

A responder may correctly recognize that useful source records could disappear. They can write an urgent, well-scoped request, obtain a decision from an accountable person and contact the custodian. None of those steps alone establishes that the underlying source has changed its deletion behavior.

This distinction is particularly important when a source's normal retention policy is short. In the fictional Harbor Library case, R15 reports that detailed booking-audit records are deleted after 24 hours unless an authorized copy is retained. R15 does not say whether the period begins at event time, ingestion time, storage time or another policy anchor. It also does not say that a source-level pause of deletion exists, is enabled, or has been requested. A responder must not add 24 hours to R9's 09:03 event time and publish an exact deletion deadline.

A preservation request asks that specified information be protected under the applicable authority and scope. A source hold—if supported by a particular system and authorized by the organization—changes or constrains the source's normal removal process for defined objects or intervals. A collected copy is an independently identified object held under its own access and retention rules. These are different things, even when the same custodial team manages them.

NIST SP 800-61 Rev. 3, especially RS.AN-06 and RS.AN-07, addresses records of investigative actions and the integrity, provenance, collection and retention of incident data. NIST SP 800-86 describes source-aware collection and preservation from an IT incident-response perspective, not as a legal preservation order. The specific hold lifecycle below is an original OpenCyber Academy teaching model; the cited sources do not prescribe its exact fields or claim that Harbor Library has such a capability.

2.8a.2 Separate three objects that may be confused

A useful incident note keeps three inventories rather than one ambiguous entry named "evidence saved":

Object What it represents What a positive entry does not prove
Source record set Events or data still maintained by the producing system or its governed storage layer That the events are complete, correct, or immune to every deletion path
Source-hold control A particular mechanism reported as protecting a defined source, selection and time interval That all records existed before activation, or that the hold covers an unrelated source
Collected evidence copy Bytes, export or image separately preserved at a specified location That the source's normal deletion was stopped, or that no source row was omitted

Suppose an authorized copy contains one booking-audit row and a SHA-256 digest matches at two checks. That may support a limited byte-consistency claim about the saved copy. It says nothing about whether the original application-audit source is still deleting rows. It also does not show that the copy contains every relevant source event.

Conversely, a confirmed source hold might keep selected records available without authorizing a broad export to the analyst. The custodian still needs permission, source-specific selection and a separate release or transfer procedure before supplying a copy. Protecting a source and collecting a reviewer copy can be complementary, but neither substitutes for the other.

The existing E1 laboratory teaches a digest-based check on a synthetic transcription; MIN2 teaches a restricted working view. HOLD2 does not repeat either. It asks whether the claimed source-level preservation effect was actually checked and what remains unproven even after a narrow positive check.

2.8a.3 Start with a decision question for P-A and P-B

At 09:20, the learner can propose two separate information paths. P-A concerns booking/application audit data relevant to the B19 edit and the limits of R14's earlier quiet-query summary. P-B concerns possible identity details that could clarify whether a session relationship is worth investigating. Their evidence value, custodians, privacy limits and loss concerns differ.

P-A is time-sensitive because R15 describes deletion of detailed booking-audit records after an unspecified 24-hour anchor. P-B may also be urgent, but the canonical record gives no identity-source retention period. An analyst should seek P-B availability information in parallel rather than borrow P-A's 24-hour rule and apply it to the identity service.

A proposed P-A preservation card should name which particular source is at risk. R9 is characterized as booking audit, while R14 is an application-audit summary. These labels must not be silently merged into one producer, one retention clock or one hold-control namespace. The custodian should confirm whether a mechanism applies to each and whether a separate request or receipt is needed.

The current investigation question might be: "Can we preserve the permitted detailed records needed to assess the B19 operation and its surrounding booking edits before the relevant source becomes unavailable?" A second, separate question asks whether limited identity details can be obtained with appropriate authority. Neither question requires collecting every patron or identity record.

The state of both P-A and P-B at the supplied Round B checkpoint is proposed. This supplement does not create a fictitious canonical approval or hold to move either card into a completed state.

2.8a.4 Define source-hold coverage as a contract, not a title

A ticket titled "hold B19 logs" is insufficient to know what would be protected. The receiving custodian needs an unambiguous control target and an authorized selection. A reviewable request should cover at least:

  1. Case and purpose: Which decision may depend on these records?
  2. Producing source: Exact storage/service and log or data collection identity, not merely "the logs".
  3. Objects: Booking IDs, event types or other identifiers within permitted scope.
  4. Time selection: Begin/end and the field used to interpret time, including whether endpoints are inclusive or exclusive.
  5. Authority: Who approved the hold request and under which organizational procedure and applicable restrictions?
  6. Custodian: Who can confirm the source's retention implementation and preserve any permitted copy?
  7. Timing: Requested start, reported effective start, permitted duration or review date, and any separate operational deadline.
  8. Intended mechanism and effect: Which deletion or retention operation should be constrained for the defined selection?
  9. Verification: What non-destructive source/control observations can challenge the claim that the hold is effective?
  10. Unresolved limits: Existing gaps, unprotected sources, unknown clock anchor and any unavailable oldest relevant row.

The field list is a teaching contract, not a legal specification or a promise that every logging system supports object-level holds. Some systems may offer retention settings, export-to-protected-storage workflows, snapshot protection or other mechanisms. They have different semantics, and a team must use the actual organization's approved procedures.

A hold on booking-audit is not necessarily a hold on application-audit or identity-detail. A hold covering 09:10–09:35 cannot establish coverage of a requested 09:00–09:30 interval. A hold covering one booking ID cannot establish coverage of every named object. Scope must be compared, not assumed from the presence of a control identifier.

2.8a.5 Approval and application produce different receipts

Suppose the fictional incident lead approves a P-A request to preserve a narrow source interval. The approval should name exactly what may be preserved and who will carry out the work. It does not establish that the custodian enabled a protective mechanism, or that the source supports one.

For a proposed operational workflow, use four initial receipt stages:

Requested. A bounded card exists. Its time and source show what was asked for, not that anyone agreed.

Approved. A responsible authority grants the defined operation and scope. The authorization may have restrictions, a deadline and a valid decision identifier. An approval for booking audit is not transferable to identity detail.

Application reported. The custodian records the applied control or other approved protective action, its target, time, identifier and intended behavior. This is an operator or system report, not an independently tested effect.

Effect checked. A reviewer assesses the reported source/control state and a bounded source-availability check against the approved selection. The result may support a limited effect claim if the method and sources are credible.

A custodian message saying "done" should therefore be followed by precise questions: done on which producer and collection, for which objects and time interval, using which control identifier, with what reported effective and review times? A positive receipt from the wrong source remains irrelevant to the requested one.

The HOLD2 script models these conditions as structured artificial fields. In a real case, a Boolean approved=True would not authenticate an actual person's decision. The team needs organizationally valid decision evidence and source-provided receipts, protected according to the applicable access and retention rules.

2.8a.6 Verify an effect without running an unsafe deletion test

A retention hold is often intended to prevent loss of data. It might appear that the simplest test is to try deleting a protected record. That can be unsafe, destructive, unauthorized or misleading. This course performs no deletion and does not recommend testing a real hold by deleting incident evidence.

For a preparation or incident review, the team can instead define non-destructive observations approved by the owner and custodian. Examples may include a governed control-status read, an audit entry recording the control's application, confirmation that the relevant retention/deletion job recognizes the protected selection, and a read-only retrieval of a known source row expected to exist.

The quality of those observations depends on what the actual source exposes. A dashboard saying "hold active" could be stale, refer to the wrong collection or omit a secondary deletion path. A successful retrieval of one older row proves that one row was accessible at that check time; it does not prove that all requested records are protected indefinitely.

A meaningful verification report should state the source and scope checked, who performed the check, the time and method, the recorded response, which expected row or control state was examined, and what could still invalidate the result.

The HOLD2 fixture uses synthetic flags for an "effect check" and an "oldest relevant row." Those are declarations inside a lab, not independent proof. The lab's strongest result is explicitly called bounded source hold confirmed in fixture, never "all deletion stopped in Harbor Library."

2.8a.7 The oldest requested row is a critical but limited sentinel

Why check an older row at all? If the request is intended to protect records already near a retention boundary, inspecting only a recent event may give false reassurance. A source might retain new rows while the oldest relevant data have already been removed.

The custodian should help identify a legitimate sentinel: a record expected to exist in the requested interval, with an identifiable source pointer and safe retrieval path. The analyst should not fabricate a row solely to make the test pass. An expected oldest row may be determined from a known record inventory, a reliable prior observation or another authorized source, subject to appropriate validation.

If the oldest relevant item cannot be retrieved, several explanations remain possible. It may have expired before the hold became effective; the source may never have generated it; a filter or index may exclude it; the request may target the wrong producer; or the hold may not cover it. The correct state is unverified coverage of that oldest item, not automatic proof of malicious deletion or proof that every part of the hold failed.

A custodian should document whether the row existed at the intended source before the request, the retrieval selection used, which storage tier was searched, and whether any source-internal transition occurred between application and check. If the cause cannot be resolved, the hold's claimed historical coverage must remain limited.

A future source-preservation mechanism cannot retroactively recreate data already removed. The team may consider authorized alternate sources or copies, but any resulting reconstruction must be documented separately from the original source hold.

2.8a.8 A hold can be valid now yet have a finite term

A source-protection mechanism may have a defined duration, expiration condition or required review. The record should separate:

A stated review date is not always the same as automatic technical expiry. A platform may continue enforcement after an administrative review is overdue, or may terminate enforcement at a lease boundary. The semantics depend on the source and control. The course must not invent them.

In HOLD2, the independent fixture provides a technical term_end. If the lab's check time is later than that term, the program returns TERM_EXPIRED_EFFECT_UNKNOWN. It does not assert that a row was deleted or that deletion resumed immediately. Actual post-term source behavior requires its own authorized observation.

A valid hold receipt also should say what happens if review cannot be completed. A safe plan may require escalation before expiration, a separately approved renewal, or continuing safeguards as defined by the actual policy. The analyst cannot assume that a prior approval renews itself.

2.8a.9 Release and expiration must not erase the earlier lifecycle

An important archival principle applies even after the preservation reason has ended: historical decisions and receipts should remain reviewable within the organization's authorized recordkeeping rules. Closing the active hold state is not permission to rewrite its earlier existence.

A source-hold ledger can therefore append lifecycle entries such as requested, approved, application reported, effect checked, review due, renewed, release approved, release reported, release checked, or term-expired status recorded. Each entry should include the responsible role, event time, source and control identifier, and a reason or decision reference where appropriate.

Do not silently overwrite an earlier ACTIVE value with RELEASED if doing so destroys information about when protection was reported and what was tested before release. Keep a current summary and the historical transitions.

A release receipt is another distinct operational event. Someone may approve the release, the custodian may report that the mechanism was removed, and a reviewer may need to confirm the current source/control state. The release should not be tested by deleting evidence in an unauthorized manner.

The HOLD2 laboratory appends a fictitious RELEASE_RECORDED entry while retaining all earlier entries. The result is RELEASE_RECORDED_RECHECK_REQUIRED, deliberately avoiding the stronger claim that every deletion behavior after release was measured. The lab performs no deletion or modification of a source.

2.8a.10 The copy remains governed separately after a source hold ends

A particular collected copy may remain subject to the organization's evidence-retention rules after a source hold is released. Conversely, a copy may have its own permitted deletion or access conditions while a source-level hold remains active. Those are separate governance and custody decisions.

Consider two fictional ledger objects:

They should not share one ambiguous status. A checked digest for copy_item_id supports a limited byte-consistency statement, but not a source-control effect. A source-control status does not automatically authorize broad distribution of copy_item_id to analysts.

The current book already discusses source/copy/interpretation and a minimized technical-review view. HOLD2 contributes the lifecycle linkage: a hold record can point to a separately authorized copy without becoming that copy, and release of one should not silently alter the other's governance.

The AR1 authority-readiness exercise in Module 1 may help identify a valid approver under a separate pre-incident process. It does not replace the case-specific approval required for P-A or P-B; nor does it provide evidence that a hold was applied during Round B.

2.8a.11 Custodian unavailable: treat nonresponse as an escalation condition

A time-sensitive request may reach an organizational mailbox while the responsible custodian is unavailable. The responder must distinguish a dispatch attempt, an acknowledgement by a role, a custodian's confirmation of applicability and an actual application/effect receipt.

If the custodian has not responded, the hold remains not confirmed. The incident lead can use the organization's approved escalation route to seek an available, authorized custodian or service owner, explain the potential loss path and preserve existing permitted records. The team must not assume that leaving a voicemail, opening a ticket or copying a supervisor creates an active source hold.

The current R15 notice increases the importance of prompt clarification, but it does not supply a verified countdown from the 09:03 R9 event. A blocked request should record the absence of the custodian, time of attempts, what was asked, any ticket/reference, known evidence already at risk, next authorized contact and next review.

The analyst must not bypass source access controls or execute retention changes using unapproved credentials. An emergency retention procedure, if one exists in a real organization, requires its own documented permission boundary and receipt. This introductory exercise invents no such power.

The HOLD2 CUSTODIAN_UNAVAILABLE negative case returns that status rather than fabricating application or verification. It does not prove records were lost or that the custodian was negligent.

2.8a.12 Contrastive example — a wrong "hold complete" message

Incorrect synthetic Round B conclusion:

"R15 says the logs last 24 hours, so the B19 row will disappear at 09:03 tomorrow. P-A has been entered as urgent and someone copied R9 into a text file. The source hold is therefore active, all relevant booking logs are safe, and P-B identity data are covered by the same hold."

Every promotion of evidence in this statement is invalid. The retention anchor is unspecified; a ticket priority does not apply a control; a copy of one item does not stop source deletion; source coverage for all booking records has not been verified; and P-B is a different source with no supplied retention policy or hold receipt.

A source reviewer cannot repair the conclusion by calculating a different timestamp. The missing information is semantic: the policy anchor, actual custody/implementation path, scope and effect of a control, and whether the oldest relevant row remains available.

A valid next step would identify the bounded P-A source request, obtain an accountable decision, ask the custodian which mechanism if any can protect it, and document only the receipts actually returned. P-B proceeds as a separate availability inquiry with its own owner and scope.

2.8a.13 Correct example — a complete but explicitly hypothetical hold receipt

Entirely invented HOLD2 rehearsal, not a Harbor Library event. On the artificial date 2040-03-15, a team prepares a request for two artificial booking-audit items, BX-01 and BX-02, over an event-time interval from 09:00 inclusive to 09:30 exclusive.

A fictional incident lead is represented as having approved the request at 09:36. The specified application custodian reports applying a source-hold control at 09:40 to booking-audit-sim covering those two objects and an enclosing 08:55–09:35 interval. The declared technical term extends to 11:30, with a separate owner review to be scheduled under the teaching contract. At 10:00, a synthetic check reports that the relevant source-protection state was observed and that the expected oldest marker was retrievable in the selected toy source.

A careful fictional conclusion is:

"Within this bounded independent fixture, the named source-control receipt covers the requested objects and event interval, has the expected custodian and a reported activation, and the declared non-destructive check at 10:00 found the oldest marker available. The check supports only the specified source/objects and observed time. It does not prove that all earlier records existed, that every deletion mechanism is constrained, that any real system was held, or that the separate copy's retention was verified."

This positive example includes source, objects, interval, authority, custodian, effective time, limited term, check method and remaining uncertainty. It is correct because its claims stay within the fictitious evidence contract.

A different result is just as educational. If the receipt covers identity-detail-sim instead of booking-audit-sim, the program refuses source coverage even if every other field looks valid. If the oldest row cannot be retrieved, the team must investigate historical coverage rather than silently mark the hold complete. If the hold term has elapsed, the earlier positive check cannot establish continued current protection.

2.8a.14 A review decision must be different from a routine expiry

At a stated review time, the owner may decide to maintain, narrow, extend, release or escalate the hold under the organization's actual policy and legal requirements. The custodian may have technical facts about control capabilities, but those facts do not automatically grant authority to make a broader business or legal preservation decision.

A renewal should receive a new recorded decision and control confirmation. It should identify whether the original mechanism continued uninterrupted or whether a gap occurred; the earlier control ID and the new decision ID should both remain in the lifecycle. "Renewed" written in a case note does not prove a platform configuration changed.

A release decision should identify the rationale and responsible authority, the affected source and objects, any continuing preservation obligation, the custodian's reported action and the post-release verification status where applicable. It also must avoid treating source-release permission as permission to delete a separately collected copy.

An expiry record may be derived from comparing time with a declared technical term, but expiration of a term is not direct observation of actual deletion. A system could continue retaining data, apply a broader policy or have already lost historical rows. The correct state in an unverified source is "term expired; current effect unknown."

These distinctions make handoffs safer. The next analyst can see which source was protected during what interval, which claims were actually verified, and which new authorization is required before the team changes a preservation control.

2.8a.15 Two different negative source outcomes

A source hold can fail acceptance in at least two important ways:

Control-path problem. The requested source or interval is not protected by the reported control, the custodian is wrong, or the application/effect receipt is missing. Here the team should correct the control request or seek a valid custodian explanation, then repeat an authorized non-destructive check.

Historical-source problem. The control appears correctly scoped for current protection, but the oldest expected row is absent. Here the team must determine whether the row ever existed at that source, whether it was already removed before application, whether the retrieval path is incomplete, or whether another storage tier is relevant. It cannot conclude immediately that the hold mechanism failed for all future records.

A third category is unknown coverage: the source does not expose enough status or row-level evidence to demonstrate the intended protection. In that case the reviewer can report that the custodian's statement was recorded but effect remains unverified, rather than replacing missing proof with an optimistic assumption.

These outcomes are different from VQ2. VQ2 concerns whether a query result supports a claim about event coverage under filters and ingestion watermark. HOLD2 concerns whether an authorized preservation control was applied to the intended source and selection, with a reviewable lifecycle. A valid hold does not make a poorly scoped query complete; a valid query does not make a source hold effective.

2.8a.15a Accept a linked evidence chain, not a collection of reassuring fields

A positive result needs more than a source name and several true flags. It needs agreement between the request, the permission actually granted, the reported control, and the observation used to assess that control. The purpose of this check is not to add paperwork: it is to prevent a valid receipt for one operation from answering a different question.

Start with three boundaries. The requested scope contains the records needed for the decision. The reported coverage describes the objects and event interval the custodian says the control covers. The authorized scope is the maximum selection the approving role permitted. For this exercise, require requested scope to fit inside reported coverage, and reported coverage to fit inside authorized scope. Check source, objects and time interval separately. Covering every requested object is not sufficient if the reported operation also includes an unapproved object.

In HOLD2, the requested event window is 09:00–09:30, while the reported control covers 08:55–09:35. The larger interval can be acceptable only with permission for that larger selection. The revised fixture supplies an explicit, invented authorization for 08:55–09:35 and BX-01/BX-02. This is additional classroom metadata, not a newly discovered Harbor Library approval. Expanding the receipt to 08:50 or adding BX-99 exceeds that permission even though the original requested records would still be covered. An empty request is rejected: mathematically, an empty set fits inside any set, but it cannot establish which evidence a preservation decision intended to protect.

Next bind the identifiers. The authorization and control receipt both name HOLD2-REQ-01; the recorded effect check names HOLD2-CTRL-01 and the same source. An approval for OTHER-REQUEST cannot be reused merely because its source name looks familiar. A result for another control cannot establish this control's effect. These comparisons detect declared inconsistencies; they cannot authenticate the issuer, prevent a forger from changing every field consistently, or establish that the named role was truly appointed.

Then inspect the meaning and order of lifecycle steps, not just whether their timestamps increase. The modeled path is request, approval, application reported and effect checked, optionally followed by release recorded. A timestamp-sorted list containing only REQUESTED is not a completed lifecycle. Nor is request, application, approval, check a valid prior-approval path simply because the timestamps increase. Under this fixture's single-application contract, the approval time must agree with its history entry, and the receipt's activation time must agree with APPLIED_REPORTED. A missing step remains missing; do not manufacture a receipt to make the sequence pass. Systems with renewals, multiple applications or different reporting-time semantics need a different documented model.

Finally, identify the observation. BX-01 is the declared sentinel for this exercise; retrieving BX-02 does not answer whether BX-01 remains available. Its selection as the oldest relevant marker is a supplied teaching premise, not something the program derives from a complete source inventory. Even a correctly bound retrieval establishes only that the selected marker was reported accessible at the recorded check. It does not demonstrate that every deletion path is constrained, every historical row existed, or every relevant object remains present.

Review question Specific check in the fixture What remains unproved
Was this selection permitted? Requested scope fits reported coverage, which fits the named authorization; role and operation agree Authentic issuance, current organizational authority and real platform permissions
Do the receipts describe one operation? Request IDs, source, control ID and modeled lifecycle agree Whether an authentic operator actually performed it
Was this the intended observation? Effect source/control and declared sentinel match Source completeness, a real protection mechanism or the reason for an absent row
Does a later review establish present protection? as_of bounds available history and checks the stated term Continued effectiveness since the last observation

as_of is an information cutoff, not a new observation. Moving it from 10:00 to 10:15 without new source evidence does not create a fresh 10:15 effect check. At the exact 11:30 term boundary, the active-term claim ends under this fixture's exclusive-end convention; the result says that current effect is unknown, not that data were deleted. A recorded release likewise requires a new authorized state check. This program records release history but does not authenticate release permission or perform release; it cannot certify that a release was lawful or technically effective.

These checks implement an original OpenCyber Academy teaching contract. NIST SP 800-61 Rev. 3, RS.AN-06 and RS.AN-07, page 29 supports recording investigative actions, safeguarding provenance and integrity, and collecting and retaining evidence under organizational procedures. It does not prescribe these identifiers, set comparisons, time limits or result labels. NIST SP 800-86 also expressly limits its forensic guidance: it is not an all-inclusive investigation procedure or legal advice.

Apply the reasoning before running Python. For EX018, keep the three-row P-A request and two-row P-A/P-B comparison; use their existing authority and receipt fields to ask for a request-bound permission, the permitted selection and the matching application/effect record. For EX019, keep E1's collection note separate from any source-control reference. For EX022, retain the five-sentence handoff and its proposed status. For EX024, keep two hypothetical trigger/response pairs: an inconsistent receipt calls for clarification and a new authorized review, not automatic containment or proof of deletion. All unprovided P-A/P-B details remain pending at 09:20. No HOLD2 identifier, timestamp or passing run belongs in R1–R16.

2.8a.16 Section synthesis — preserve the source, the copy and the decision trail separately

The learner should finish with three defensible habits. First, name the source, authorized objects and interval precisely enough that a custodian can say what is and is not protected. Second, separate requested, approved, applied and verified states, and use non-destructive source observations to bound any effect claim. Third, keep a versioned or append-only lifecycle through review, expiry and release without erasing earlier decisions or equating a protected copy with protected source retention.

For Harbor Library at 09:20, P-A and P-B remain proposed. R15 leaves the exact deletion anchor unknown. No fictional HOLD2 positive result, expiry or release may be imported into R1–R16. The pending task is to obtain an authorized, narrowly scoped custodian clarification and document whatever the real source could verify under its actual procedures.

2.8b HOLD2 offline laboratory — source hold lifecycle and coverage

Environment: Python 3 standard library, entirely in memory. No file creation, network access, credentials, data collection, retention-setting changes, destructive probes or deletion.

Fixture classification: A separate artificial 2040-03-15 scenario; the source names booking-audit-sim and identity-detail-sim, objects BX-01/BX-02 and hold receipts are invented. They are not R-series records or real P-A/P-B execution evidence. Goal: Decide whether a described source hold has sufficient bounded simulated source/custodian/scope/effect evidence, and refuse broader conclusions when a required step is missing or a term has elapsed.

Assumptions and observations to predict

A request covers two artificial records in the interval 09:00 ≤ event < 09:30 UTC. An invented approving role has accepted its scoped source, and the invented application custodian reports applying a control at 09:40 that covers 08:55–09:35. The fixture checks state at 10:00 with an artificial effect-check flag and oldest-row availability flag. Its reported technical term ends at 11:30.

The program verifies declared consistency and prints a reason when it refuses acceptance. The Boolean fields are invented teaching assertions, not authenticated approval, actual source protection or proof of deletion prevention.

Complete Python 3 program

Execution contract: Run this whole listing in a fresh Python 3 session, not after another laboratory that reuses BASE or utc. It prints 33 lines: the previous sixteen baseline lines, three chronology controls and fourteen additional acceptance controls. All times belong to the artificial UTC date 2040-03-15. The explicit authorization, request/control IDs and sentinel binding are invented additions to HOLD2 only. They do not authenticate an issuer or add a case approval to R1–R16.

from copy import deepcopy
from datetime import datetime, timedelta
import re

def utc(value):
    return datetime.fromisoformat(
        f"2040-03-15T{value}:00+00:00"
    )

REQUEST = {
    "id": "HOLD2-REQ-01",
    "sentinel": "BX-01",
    "source": "booking-audit-sim",
    "objects": {"BX-01", "BX-02"},
    "interval": (utc("09:00"), utc("09:30")),
    "custodian": "AppCustodian",
}
RECEIPT = {
    "id": "HOLD2-CTRL-01",
    "request_id": "HOLD2-REQ-01",
    "source": "booking-audit-sim",
    "objects": {"BX-01", "BX-02"},
    "interval": (utc("08:55"), utc("09:35")),
    "custodian": "AppCustodian",
    "active_from": utc("09:40"),
    "term_end": utc("11:30"),
}
AUTHORIZATION = {
    "request_id": "HOLD2-REQ-01",
    "operation": "hold_source",
    "source": "booking-audit-sim",
    "objects": {"BX-01", "BX-02"},
    "interval": (utc("08:55"), utc("09:35")),
    "approver": "IncidentLead",
    "custodian": "AppCustodian",
    "approved_at": utc("09:36"),
    "valid_until": utc("11:30"),
}
BASE = {
    "authorization": AUTHORIZATION,
    "effect_control_id": "HOLD2-CTRL-01",
    "effect_source": "booking-audit-sim",
    "oldest_checked": "BX-01",
    "request": REQUEST,
    "approved": True,
    "approval_source": "booking-audit-sim",
    "receipt": RECEIPT,
    "custodian_available": True,
    "effect_checked": True,
    "oldest_retrievable": True,
    "as_of": utc("10:00"),
    "history": (
        ("REQUESTED", "09:34"),
        ("APPROVED", "09:36"),
        ("APPLIED_REPORTED", "09:40"),
        ("EFFECT_CHECKED", "10:00"),
    ),
    "copy_retained": False,
}

def input_problem(s):
    """Check the fixed teaching schema; never authenticate a real source."""
    if not isinstance(s, dict) or set(s) != set(BASE):
        return "INVALID_PACKET_SCHEMA"
    for field in ("approved", "custodian_available", "effect_checked",
                  "oldest_retrievable", "copy_retained"):
        if type(s[field]) is not bool:
            return "NON_BOOLEAN:" + field
    for field in ("approval_source", "effect_control_id", "effect_source",
                  "oldest_checked"):
        if not isinstance(s[field], str) or not s[field]:
            return "INVALID_IDENTIFIER:" + field
    objects = (("request", REQUEST), ("authorization", AUTHORIZATION))
    if s["receipt"] is not None:
        objects += (("receipt", RECEIPT),)
    times = [s["as_of"]]
    for name, model in objects:
        item = s[name]
        if not isinstance(item, dict) or set(item) != set(model):
            return "INVALID_OBJECT_SCHEMA:" + name
        for field, value in item.items():
            if isinstance(model[field], str):
                if not isinstance(value, str) or not value:
                    return "INVALID_IDENTIFIER:" + name + "." + field
        selected = item["objects"]
        if (not isinstance(selected, (set, frozenset)) or not selected
                or any(not isinstance(x, str) or not x for x in selected)):
            return "INVALID_OBJECT_SCOPE:" + name
        window = item["interval"]
        if not isinstance(window, tuple) or len(window) != 2:
            return "INVALID_INTERVAL:" + name
        times.extend(window)
    times.extend((s["authorization"]["approved_at"],
                  s["authorization"]["valid_until"]))
    if s["receipt"] is not None:
        times.extend((s["receipt"]["active_from"], s["receipt"]["term_end"]))
    for value in times:
        if (not isinstance(value, datetime) or value.tzinfo is None
                or value.utcoffset() != timedelta(0)
                or value.date().isoformat() != "2040-03-15"):
            return "INVALID_UTC_TIME"
    for name, _ in objects:
        if s[name]["interval"][0] >= s[name]["interval"][1]:
            return "INVALID_INTERVAL:" + name
    if not isinstance(s["history"], tuple):
        return "INVALID_HISTORY_SCHEMA"
    for entry in s["history"]:
        if (not isinstance(entry, tuple) or len(entry) != 2
                or not all(isinstance(x, str) for x in entry)):
            return "INVALID_HISTORY_SCHEMA"
        if not re.fullmatch(r"[0-9]{2}:[0-9]{2}", entry[1]):
            return "INVALID_HISTORY_CLOCK"
        try:
            utc(entry[1])
        except ValueError:
            return "INVALID_HISTORY_CLOCK"
    return None


def status(s):
    problem = input_problem(s)
    if problem is not None:
        return problem
    req, rec = s["request"], s["receipt"]

    if not s["approved"]:
        return "PROPOSED_ONLY"
    if s["approval_source"] != req["source"]:
        return "APPROVAL_NOT_FOR_SOURCE"
    if not s["custodian_available"]:
        return "CUSTODIAN_UNAVAILABLE"
    if rec is None:
        return "APPROVED_APPLICATION_UNCONFIRMED"
    if rec["source"] != req["source"]:
        return "WRONG_SOURCE"
    if rec["custodian"] != req["custodian"]:
        return "WRONG_CUSTODIAN"
    if (
        not req["objects"].issubset(rec["objects"])
        or rec["interval"][0] > req["interval"][0]
        or rec["interval"][1] < req["interval"][1]
    ):
        return "SCOPE_GAP"
    if s["as_of"] < rec["active_from"]:
        return "NOT_YET_ACTIVE"

    if rec["term_end"] <= rec["active_from"]:
        return "INVALID_CONTROL_TERM"
    trail = [(kind, utc(clock)) for kind, clock in s["history"]]
    if (
        not trail
        or any(trail[i][1] > trail[i + 1][1]
               for i in range(len(trail) - 1))
        or any(when > s["as_of"] for _, when in trail)
    ):
        return "HISTORY_NOT_AVAILABLE_AS_OF"

    authorization = s["authorization"]
    if (authorization["request_id"] != req["id"]
            or rec["request_id"] != req["id"]):
        return "REQUEST_BINDING_MISMATCH"
    if (authorization["source"] != req["source"]
            or authorization["operation"] != "hold_source"):
        return "AUTHORIZATION_TARGET_MISMATCH"
    if (authorization["approver"] != "IncidentLead"
            or authorization["custodian"] != req["custodian"]):
        return "AUTHORIZATION_ROLE_MISMATCH"
    if (not rec["objects"].issubset(authorization["objects"])
            or rec["interval"][0] < authorization["interval"][0]
            or rec["interval"][1] > authorization["interval"][1]):
        return "AUTHORIZED_SCOPE_EXCEEDED"
    if (authorization["approved_at"] > rec["active_from"]
            or authorization["valid_until"] < rec["term_end"]):
        return "AUTHORIZATION_TIME_MISMATCH"
    expected = ("REQUESTED", "APPROVED", "APPLIED_REPORTED", "EFFECT_CHECKED")
    kinds = tuple(kind for kind, _ in trail)
    if kinds not in (expected, expected + ("RELEASE_RECORDED",)):
        return "HISTORY_LIFECYCLE_MISMATCH"
    if trail[1][1] != authorization["approved_at"]:
        return "APPROVAL_TIME_MISMATCH"
    if trail[2][1] != rec["active_from"]:
        return "ACTIVATION_TIME_MISMATCH"
    if (s["effect_control_id"] != rec["id"]
            or s["effect_source"] != rec["source"]):
        return "EFFECT_BINDING_MISMATCH"
    if (req["sentinel"] not in req["objects"]
            or s["oldest_checked"] != req["sentinel"]):
        return "SENTINEL_BINDING_MISMATCH"

    # Preserve earlier steps; a release is an appended event.
    if "RELEASE_RECORDED" in [
        kind for kind, _ in s["history"]
    ]:
        return "RELEASE_RECORDED_RECHECK_REQUIRED"
    if s["as_of"] >= rec["term_end"]:
        return "TERM_EXPIRED_EFFECT_UNKNOWN"
    if not s["effect_checked"]:
        return "EFFECT_NOT_VERIFIED"
    if not s["oldest_retrievable"]:
        return "OLDEST_ROW_UNAVAILABLE"

    return "BOUNDED_SOURCE_HOLD_CONFIRMED_IN_FIXTURE"

def variant(changes):
    row = deepcopy(BASE)
    row.update(changes)
    return row

CASES = [
    ("VALID_BOUND", {}),
    ("PROPOSED_ONLY", {"approved": False, "receipt": None}),
    ("APPROVED_NO_APPLY", {"receipt": None}),
    (
        "COPY_ONLY",
        {"approved": False, "receipt": None,
         "copy_retained": True},
    ),
    (
        "APPROVAL_WRONG_SOURCE",
        {"approval_source": "identity-detail-sim"},
    ),
    (
        "RECEIPT_WRONG_SOURCE",
        {"receipt": {
            **RECEIPT, "source": "identity-detail-sim"
        }},
    ),
    (
        "RECEIPT_SCOPE_GAP",
        {"receipt": {
            **RECEIPT, "objects": {"BX-01"}
        }},
    ),
    (
        "WRONG_CUSTODIAN",
        {"receipt": {
            **RECEIPT, "custodian": "OtherCustodian"
        }},
    ),
    (
        "CUSTODIAN_UNAVAILABLE",
        {"custodian_available": False},
    ),
    (
        "OLDEST_MISSING",
        {"oldest_retrievable": False},
    ),
    (
        "NO_EFFECT_PROBE",
        {"effect_checked": False},
    ),
    (
        "NOT_YET_ACTIVE",
        {"as_of": utc("09:38")},
    ),
    (
        "TERM_EXPIRED",
        {"as_of": utc("11:45")},
    ),
    (
        "RECEIPT_WINDOW_GAP",
        {"receipt": {
            **RECEIPT,
            "interval": (utc("09:10"), utc("09:35"))
        }},
    ),
    (
        "RELEASE_RECORDED",
        {
            "as_of": utc("10:15"),
            "history": BASE["history"] + (
                ("RELEASE_RECORDED", "10:05"),
            ),
        },
    ),
]

for label, changes in CASES:
    print(f"{label}: {status(variant(changes))}")

print(
    "HISTORY_RELEASE:",
    " -> ".join(
        kind for kind, _ in CASES[-1][1]["history"]
    ),
)

assert (
    status(variant({}))
    == "BOUNDED_SOURCE_HOLD_CONFIRMED_IN_FIXTURE"
)
assert (
    status(variant(CASES[-1][1]))
    == "RELEASE_RECORDED_RECHECK_REQUIRED"
)

# Negative controls remain outside the R-series case record.
future_release = variant({
    "history": BASE["history"] + (("RELEASE_RECORDED", "10:05"),)
})
early_review = variant({"as_of": utc("09:45")})
invalid_term = variant({
    "receipt": {**RECEIPT, "term_end": utc("09:35")}
})
for label, sample in (
    ("FUTURE_RELEASE", future_release),
    ("FUTURE_EFFECT_CHECK", early_review),
    ("INVALID_TERM", invalid_term),
):
    print(f"{label}: {status(sample)}")
assert status(future_release) == "HISTORY_NOT_AVAILABLE_AS_OF"
assert status(early_review) == "HISTORY_NOT_AVAILABLE_AS_OF"
assert status(invalid_term) == "INVALID_CONTROL_TERM"

# Additional independent acceptance controls, not R-series events.
CONTROLS = [
    ("EMPTY_OBJECTS", {"request": {**REQUEST, "objects": set()}},
     "INVALID_OBJECT_SCOPE:request"),
    ("REVERSED_INTERVAL", {"request": {**REQUEST,
        "interval": (utc("09:25"), utc("09:05"))}},
     "INVALID_INTERVAL:request"),
    ("TEXT_FALSE", {"approved": "False"}, "NON_BOOLEAN:approved"),
    ("MISSING_APPLICATION", {"history": (
        ("REQUESTED", "09:34"), ("APPROVED", "09:36"),
        ("EFFECT_CHECKED", "10:00"))}, "HISTORY_LIFECYCLE_MISMATCH"),
    ("APPROVAL_AFTER_APPLY", {"authorization": {
        **AUTHORIZATION, "approved_at": utc("09:45")}},
     "AUTHORIZATION_TIME_MISMATCH"),
    ("REUSED_APPROVAL", {"authorization": {
        **AUTHORIZATION, "request_id": "OTHER-REQUEST"}},
     "REQUEST_BINDING_MISMATCH"),
    ("EXTRA_OBJECT", {"receipt": {
        **RECEIPT, "objects": {"BX-01", "BX-02", "BX-99"}}},
     "AUTHORIZED_SCOPE_EXCEEDED"),
    ("WIDER_INTERVAL", {"receipt": {**RECEIPT,
        "interval": (utc("08:50"), utc("09:35"))}},
     "AUTHORIZED_SCOPE_EXCEEDED"),
    ("WRONG_EFFECT_CONTROL", {"effect_control_id": "OTHER-CONTROL"},
     "EFFECT_BINDING_MISMATCH"),
    ("WRONG_SENTINEL", {"oldest_checked": "BX-02"},
     "SENTINEL_BINDING_MISMATCH"),
    ("ACTIVATION_DISAGREES", {"receipt": {
        **RECEIPT, "active_from": utc("09:41")}},
     "ACTIVATION_TIME_MISMATCH"),
    ("NAIVE_REVIEW", {"as_of": datetime(2040, 3, 15, 10)},
     "INVALID_UTC_TIME"),
    ("INVALID_HISTORY_CLOCK", {"history": (("REQUESTED", "25:99"),)},
     "INVALID_HISTORY_CLOCK"),
    ("EXACT_TERM_END", {"as_of": utc("11:30")},
     "TERM_EXPIRED_EFFECT_UNKNOWN"),
]
for label, changes, expected in CONTROLS:
    actual = status(variant(changes))
    assert actual == expected, (label, actual, expected)
    print(f"{label}: {actual}")

Before reading the final appendix, predict all 33 output lines: sixteen baseline lines, three chronology controls and fourteen acceptance controls. Explain the first blocking condition for each variant. Compare the actual run with the HOLD2 worked result.

Required learner artifacts: Reproduce the 33 output lines; create a scenario table with the first blocking condition and a safe next request; identify why COPY_ONLY does not establish source hold and why OLDEST_MISSING does not prove deletion timing; compare requested, reported and authorized scope; identify the request/control/sentinel bindings and required lifecycle steps; propose a reviewer check for release and expiry that does not erase history or delete data. A future lifecycle entry cannot support an earlier as_of conclusion; even a consistent fixture does not authenticate a real hold.

Five-point assessment for this unnumbered lab: One point each for exact output; correct source/object/interval coverage and authorization reasoning; separation of copy from source control; correct treatment of unavailable custodian or a specifically identified oldest row; and complete request-bound lifecycle, expiry/release history and explicit effect limits. Assess the added controls within these same five criteria. The lab adds no new EX identifier.

2.8c Practical two-role activity — custodian packet and independent review

Purpose: Demonstrate that a second person can distinguish a requested, approved, applied and verified source hold without relying on the packet author's explanation.

Roles: Custodian / Packet Author and Independent Reviewer. The incident-lead approval is represented only by a fictional classroom request card. There is no real source custodian, logging system or deletion mechanism involved.

Step 1 — Freeze the source-hold request

The packet author creates HOLD2-request-v1 with the fictional source, object IDs, time interval, purpose, proposed approval, custodian, requested hold mechanism, earliest relevant row and expected review terms. Mark the actual custodian acknowledgement, control identifier, effect check and observed oldest-row state not supplied until the artificial receipt card is given.

Keep a separate copy-item card, if using one, with its own retention and integrity fields. Do not allow a saved copy to change the source-hold status.

Step 2 — Prepare and freeze one simulated custodian response

Choose the valid HOLD2 fixture or a wrong-source, oldest-missing, reused-approval or wrong-effect-control variant. Record the requested selection, the explicit authorization envelope, request and control IDs, application time, technical term, declared sentinel, check response and missing fields. Keep the complete modeled lifecycle and distinguish an unverified issuer from a structurally matching identifier. Freeze the packet as HOLD2-custodian-v1; a positive script result does not replace the receiver's independent reconstruction.

The reviewer must not see the author's private reasoning or a corrected answer. The packet may include explicit approved source pointers and the relevant original teaching rules.

Step 3 — Independent review with no author assistance

The reviewer receives the two frozen cards and must answer:

  1. What was requested, and was the request approved for that exact source and selection?
  2. Which source, objects and interval did the custodian report protecting?
  3. Does the receipt identify the appropriate custodial role, activation time, duration or review condition?
  4. Which non-destructive effect observation is provided, and which expected oldest source row was or was not retrieved?
  5. Is the current state confirmed for this narrow scope, merely reported, unverified, expired, released, or awaiting escalation?
  6. What is the safest next authorized request, and what claim remains unsupported?
  7. Is there a separately retained copy, and why does it not settle the source-hold question?

The reviewer saves HOLD2-review-v1 before discussion. Missing fields must remain missing. The reviewer should not claim that a source was deleted or that a hold succeeded solely because the author used reassuring wording.

Step 4 — Evaluate, then correct with a new version

Compare the frozen response with the request and receipt. Identify whether a discrepancy came from the packet's missing field, the reviewer's interpretation, or an unavailable custodian/source. Retain the original versions. If a change is needed, write HOLD2-request-v2 or HOLD2-custodian-v2 and run another separately marked review; do not rewrite the first attempt.

Pass: The reviewer locates the source/scope, distinguishes proposed/approved/applied/verified states, recognizes the meaning of the oldest-item check, does not calculate a deadline from R15's unknown anchor, and chooses a safe hold/escalation or recheck.

Critical fail: The reviewer calls a proposed request an active hold, treats a copy as evidence that deletion stopped, accepts a wrong-source/wrong-object receipt, assumes an absent oldest row was deleted at an invented time, or authorizes an intrusive test without permission.

Limit: This tabletop and the Python output measure only consistency and independent reasoning on synthetic records. They do not prove organizational readiness, actual source preservation, legal compliance or completion of any Harbor Library case action.

Worked checkpoint

A custodian may acknowledge a hold request while its effect remains unverified. The case record should show request, approval, application report, effect check and expiry separately; a downloaded copy has its own custody trail.

Practice — Lesson 08

EX018 — Retention decision

Objective: prepare a proportionate preservation decision. Inputs: R9, R13–R15, the collection-note fields in section 2.3 and the worked queue in section 2.4. Output: a three-row P-A request to the application custodian stating each source and proposed event range, deletion-policy anchor or actual deadline, and collector/authority/storage scope; add one sentence explaining why preservation may precede root-cause knowledge. Then add a two-row comparison of P-A with P-B: decision each could change, known or unknown loss path, owner, present state and why the second availability check may proceed in parallel. Do not calculate a precise expiry merely by adding 24 hours to R9's timestamp or claim either source was collected. A score of 2 identifies the time-sensitive risk, privacy boundary and proposal-versus-collection distinction for both sources.

Extension: Include a specific question that the application custodian must answer about the deletion-policy anchor and a separate question about whether the oldest requested row is still retrievable. State the status of P-A and P-B using the exact words proposed, approved, collected or verified, without skipping intermediate states.

For full credit: A 24-hour rule is a duration, not a confirmed deletion instant; P-A's potential urgency does not authorize a bulk export or establish that a hold took effect.

MIN2 supplementary task (after the required artifact):

Additional task: Alongside the P-A and P-B proposed requests, identify the specific columns necessary for the next decision and a category of source field that should not automatically be distributed to the technical reviewer. Distinguish retention of a permitted source object from permission to distribute every column. Preserve the existing R15 unknown policy anchor and proposal-versus-collection states.

For full credit: The request names the business purpose, source selection, custodians, approving role and restricted reviewer scope. No completed export or broad personal-data permission is invented.

HOLD2 supplementary task (after the required artifact): Keep the original three-row P-A request and two-row P-A/P-B comparison. Add to the existing custodian-question field the exact source-hold receipt requirements: source namespace, approved booking/object IDs, event interval/time semantics, accountable authority, custodian, reported activation, review/expiry terms, observed effect and an explicit limit. State that a missing oldest requested row requires investigation rather than a fabricated expiry. Do not change P-A or P-B from proposed merely because HOLD2 contains a positive artificial run.

For full credit: The request remains a proposed authorized next step at 09:20, the R15 policy anchor remains unknown, the P-B retention rule remains unspecified, and neither a source hold nor a copy is claimed performed.

Worked answer: EX018 in the final appendix.

Continue studying — lesson 08 of at least 20

← Lesson 07 · Course lesson index · Lesson 09 →

Continue to the next authored daily lesson.

Worked answers

EX018 — Worked result

P-A request element Specific source, object and proposed event interval Policy-anchor / oldest-row question Authority, custodian, storage and state
1. Detailed booking audit relevant to R9 Proposed booking-audit source for B17–B19; requested 08:30–09:20 UTC event-time range, subject to custodian confirmation. R15 gives a 24-hour duration but no verified start anchor or exact expiry. Which relevant row is oldest and still retrievable? Incident lead to approve; booking/application custodian to confirm producer and availability. Restricted collector and copy location remain planned. Proposed, not created.
2. Application-audit summary behind R14 Separately named application-audit source; proposed 08:30–09:20 UTC selection for custodian review. Query filters, producer and index coverage are not supplied. Does its own retention rule differ from R15? What interval and ingestion state did the original query actually cover? Incident lead to approve only minimum necessary selection; application/logging custodian to specify producer, collector and restricted storage. No re-run or export shown. Proposed.
3. P-A authority and copy-control decision Keep both source namespaces, object IDs and selected intervals distinct. Writing P-A does not create a collection or hold. Confirm each source's policy anchor, earliest relevant row, potential loss path and any separate hold capability and effect check. Incident lead owns approval under the fictional rules; name executing custodian and collector only after permission. Document intended restricted location, access list, receipts and review trigger. Proposed, not approved, collected or verified.

A prompt, bounded preservation proposal may be justified before the cause of B19's edit is known because a relevant source might become unavailable, but R15 alone does not prove when deletion occurs, that a hold exists or that a collection has taken place.

Comparison at 09:20 Decision value and loss path Owner, state and limit
P-A booking and application audits Could test the B19 edit and R14's quiet-query coverage, if the sources and selection are distinguished. R15 reports a 24-hour deletion rule, but its start point and actual source availability remain unknown. Incident lead seeks approval; application custodian confirms each source, a narrow selection and policy. Proposed, not collected; no current-state or completeness proof.
P-B identity detail Could test whether a session key connects records, if both sources share its meaning. R13 omits device/location and no identity-source retention period is supplied. Incident lead asks identity administrator about availability and minimal fields in parallel. Proposed, not collected; no human attribution.

The comparison does not mean that only P-A matters or that urgency authorizes a bulk identity export. A valid answer may choose a different order if it names a documented loss condition and approval path; it must leave unsupported source coverage and actor identity unresolved.

Further reasoning: A complete P-A request asks which producer emitted the R9 booking audit and which produced R14's application-audit summary before proposing that their rows be joined. It names B17–B19, a bounded event range, minimum necessary fields and the application custodian. The custodian must establish what starts R15's 24-hour clock and whether the oldest relevant detailed row is still accessible. The incident lead owns approval, and the retained object would need its own source, method, access and collection receipt. At the supplied 09:20 state, P-A and P-B remain proposed; P-B can investigate identity-detail availability and its unknown retention in parallel. Neither request is an approved export, an effective hold or a verified copy. The inability to compute a deadline is an explicit result, not a reason to defer contacting the custodian.

MIN2 worked extension:

At 09:20, P-A can be proposed to the application custodian for a bounded booking-audit selection relevant to B17–B19 and R14's source-coverage question, while P-B can ask the identity custodian about available session detail under separate approval. A technical review may need source event ID, booking ID, event time, operation type and an appropriate account/session pointer. It does not automatically need a patron contact address, newsletter membership or unrelated booking records. R15 reports a 24-hour deletion policy but not its anchor or exact deadline. Source preservation, requested field selection, reviewer access and actual collection require distinct statuses and authority. No completed export or active retention hold is supplied.

HOLD2 worked extension:

At 09:20, the P-A card can request an authorized, bounded check of relevant booking-audit and application-audit sources, explicitly distinguishing their producers and retention semantics. The three-row table asks (1) which source and interval are involved; (2) what starts R15's 24-hour policy clock and whether the oldest needed row is still retrievable; and (3) who approves, applies, verifies and stores any authorized copy or source control. An effective source-hold receipt, if the custodian later supplies one, would identify its source, object set, interval, authority, custodian, reported start, term/review, effect observation and limit. The P-A/P-B comparison retains separate custodians and unknown P-B retention. Both requests remain proposed in R1–R16. The isolated HOLD2 result does not prove Harbor Library preserved any data, and a missing oldest row would require source-coverage investigation, not a fabricated deletion time.