-
Scope + the high-risk gate (Kent C020; blueprint decision #10). State exactly what is being collected
and why. Decline a classified-adjacent tasking here (invariant 5). Collection targeting a named private
individual is gated — apply the confirmation gate before any search; do not fish for a person. Re-apply
the gate if a newly identified named private individual surfaces mid-investigation.
-
Search (osint-toolkit:search, one connector) → candidate results (FM 2-22.3 C023). The pre-egress
gate screens the query; never put case/source identifiers into an outbound query.
Degraded mode (OSINT_LIVE=0): execute step 1, issue the search (the guard/pre-egress gate/audit run but
it returns no live bytes), then stop — do not proceed to steps 3–7. Hand back an empty EvidenceItem[]
with live_collection=false; never fabricate content against empty results (fail-closed).
-
Fetch (osint-toolkit:fetch) only a URL returned by a prior search result (FM 2-22.3 C023). A
near-miss URL (not in the search provenance set) is gated: apply the confirmation gate, then call
osint-toolkit:fetch(url, confirmed=True). The SSRF guard + audit run before anything leaves.
-
Archive integrity (Heuer, ACH Step 2): osint-toolkit:compute_hash (content hash) and, for images,
osint-toolkit:extract_exif. Both are candidate — verify a detected type/location in step 6, never
assume it.
-
Archive as an ingested proposal (osint-toolkit:propose_to_ledger) — source_channel='ingested',
ungraded, hash-anchored, with the REQUIRED pii flag (invariant 1; FM 2-22.3 C027). Set pii=true
if step 1's named-private-individual gate fired for this item, or if step 4's EXIF/content identifies a
private individual not already covered by step 1; otherwise false. This makes the durable,
provenance-tracked record before any conclusion is derived from the item. Its note is an unverified
annotation, never a judgment. Returns the ledger item id used by step 6. Then call
osint-toolkit:verify_chain(item_id) to confirm the hash chain is intact before returning the id — on
failure, flag it and abort the item rather than carrying an unverifiable record forward.
-
Verify against the ledger item — candidate status, confirmed downstream (Heuer, ACH Step 2; blueprint decision #10).
Geolocation / chronolocation / cross-source corroboration is analysis, not a tool result — it produces a
per-claim verification status for the ledger item (distinct from the per-item A–F/1–6 grade, which
is step 7's job). Tools available here, each producing candidates:
osint-toolkit:get_map_tile(lat, lon, zoom, connector) — pull a candidate tile to compare against an
image for geolocation.
osint-toolkit:reverse_image_search(artifact_ref, connector, confirmed=False) — treat as
fetch-equivalent egress: it uploads the subject's likeness to a third party, so apply the
confirmation gate (disclosing the likeness will leave the environment) and only then call it with
confirmed=True.
For a large verification fan-out, delegate to a Task subagent. Enforcement boundary — be honest about
it: a calling skill's prose cannot strip a Task / general-purpose subagent's tool palette (that
palette is fixed by the subagent's own definition), so a sentence here telling it to "withhold WebFetch /
Bash" is not a runtime control — it is the same known-enforcement-gap class the file already discloses
for invariant 5, not effective enforcement of the sole-egress surface (invariant 4). What does bound the
blast radius, and is real: grant the subagent no ledger-read and no osint-toolkit:*, and pass it,
inline, only the one ledger item's already-fetched content + the verification question — so it has nothing to
use even if its definition holds a network tool; and require the return payload to be exactly
{verification, confidence, rationale}, letting only that re-enter the main thread (keep raw, untrusted
material out of the main context). Standing fix (the actual enforcement): define a dedicated
geo-chrono-verifier subagent with an explicit restricted tools: allowlist (verification reasoning only;
no WebFetch / Bash / network tool) and delegate to that by name. If verification turns out to require a
new egress (another fetch, a map tile, a reverse-image upload), the subagent must not perform it — it
returns that need, and the main thread issues the call through this skill's gated path
(confirmation gate + ). Carry the returned as a status on the
handed to grading (step 7) and, later, the Assessment — it is confirmed at the
report+approve human gate (structured-analysis Step 10; Kent C020, Heuer C167), not here.
no or tool writes a verification annotation
back onto the stored ledger item, so the status travels , not as a ledger write.
Persisting it on the ledger item would need a new -style tool (with a
/ param mirroring the fetch/upload gates) — flagged here, not invented.
-
Hand off to grade — do not grade here (FM 2-22.3 C428; Masterman C044/C002). Invoke the
source-evaluation skill on the ingested item synchronously and wait for it; this skill computes no
grade of its own, but the returned items carry the grade source-evaluation assigns. It assigns
reliability A–F / credibility 1–6,
diagnosticity, corroboration, and the deception check (the subject may control the footprint). Escalate to
the deception-detection-reviewer subagent (via Task) when a concrete D&D trigger fires —
corroboration fails across independent channels, or the source has a prior manipulated-media /
feedback-controlled history — not on a vague "serious risk". Only a confirmed grade lets the item into the
ACH matrix. (Deception-detection-reviewer is deferred behind its security-review gate — see Status.)