Investigation Review Hub — production gap & remediation analysis
What these tasks are
Outside counsel / legal-ops needs a single structured JSON object that turns
the state of one litigation matter into a gap-and-remediation deliverable:
material production gaps and defects, per-category coverage, retained/available
remediation sources, numeric privilege & QC metrics, and a prioritized action
plan with owners. The exact key names, enum vocabularies, metric list, and
ordering change every task — the only fixed input is the matter and the
answer_template.json you are handed. Never reuse another task's field names,
enum values, or numbers; derive them from this task's template and hub data.
The Investigation Review Hub is the sole source of business evidence. The
task's local payload (request_context.json / review_scope.json /
matter_context.json) supplies only context: matter_id, client, category
codes/labels, API config, cutoff. Do not read environment source files,
database/seed files, generated manifests, hidden notes, or any answer/evaluation
file — event and source evidence must come from the hub.
Operating procedure
Read the context payload in input/payloads/ — capture matter_id,
client, category-code family, review cutoff, and any allowed/excluded-source
notes. This tells you which matter and gives human-readable category labels.
Read input/payloads/answer_template.json and treat it as the contract.
Extract, for this task specifically:
required_top_level_keys (the object's shape),
- each list's
item_required_keys and field types,
- the
enums / enum_choices (you MUST emit only these exact strings),
ordering_rules (how to sort each list), and
- the
metrics required keys with their precise definitions.
The template defines the schema; it never contains the answer. See
references/output_contract.md for the recurring 5-part archetype that these
templates all instantiate under different names.
Get network config from environment_access.md (the only file to use for
network access): the base URL (GDPEVO_ENV_BASE_URL), the X-API-Key
header value, and the allowed endpoint list. Send the X-API-Key header on
every request. Do not hardcode a base URL or key — read them each run.
Pull matter-scoped evidence from the hub. Confirm the matter via
GET /api/matters, then read the evidence tables — always filtered to this
matter_id. GET endpoints accept ?matter_id=<id> (and other column
filters) and return normalized arrays; POST /api/query runs read-only SQL
({"sql": "..."} → {columns,row_count,rows,truncated}) for joins and
aggregation. Endpoint→table map, field semantics, and query recipes are in
references/hub_api.md. Note hold_date from the matter — it is the pivot
for retention classification.
Classify each candidate into material findings vs. noise, and map raw hub
values to this template's enums, using references/gap_classification.md.
Core judgments that recur:
- Pre-hold, policy-compliant destruction is NOT a preservation failure
(
event_date < hold_date and within retention_period_months); only
post-hold loss is spoliation to disclose.
- Uncollected / partially collected personal or key sources = collection gap.
retained / available archives limit irretrievable loss for the
categories they cover — list them as remediation sources.
- Responsiveness miscoding → recode & produce; privilege log gaps
(
withheld_count > logged_count) → supplement log; over-designation /
miscoded privilege → re-review/downgrade; third-party entries →
waiver assessment; a zero-production claim contradicted by responsive docs
→ readiness blocker; should_exist_missing → locate missing record.
- Filter distractors: routine QC (
metadata_gap, duplicate_overlay),
issue_tags: routine, and *-NOISE-* / sampling actions are not material
unless the template's definitions pull them in.
Compute metrics exactly as the template defines them, as whole integers.
Recurring identity: unlogged = withheld_count − logged_count. Honor
scoping qualifiers in a metric's description (e.g. "from selected
incomplete-log blockers only") rather than summing every row. Booleans like
production_ready/rolling_production_ready are true only when no material
blocker remains for any in-scope category.
Use stable hub IDs verbatim for every id/ref field — event_id,
source_id, finding_id, entry_id, action_id, doc_id, and
category_code exactly as returned. Never invent, renumber, or reformat IDs.
Ref lists (source_refs, issue_refs, blocking_refs, target_refs,
category sets) are sorted ascending.
Build the action plan from remediation_actions where they exist, mapping
the hub's human-readable owner and action_type to the template's owner
and action_type enums, and its priority/severity to the template's
priority enum. Rank by severity/production impact with 1 = highest; make
each material finding traceable to an action and vice-versa.
Assemble, order, and validate. Include only material/non-complete items
where the template scopes a list that way. Ensure every required_top_level_key
is present, every item_required_key is present on every item (use 0 for
N/A integers, null for N/A strings/dates), every enum value is legal, and
every list obeys its ordering_rules. Cross-check that findings, category
coverage, sources, metrics, and actions tell one consistent story.
Output exactly one JSON object and nothing else — no prose, no code
fences, no trailing commentary.
Guardrails
- Hub = evidence; payload = context/labels; nothing else is a source.
- The template is authoritative for names/enums/order/precision — re-read it per
task; do not carry over vocabulary from a prior matter.
- Every hub read is filtered to the current
matter_id (the hub holds many
matters).
- Emit only enum strings that appear in this template; when unsure, pick the
closest legal value and keep it consistent across sections.
1---2name: investigation-review-hub-gap-analysis-23description: Produce a structured-JSON e-discovery gap / remediation dashboard for a legal investigation matter (grand jury or SEC/DOJ subpoena) by pulling matter-scoped evidence from the Investigation Review Hub API and mapping it onto a task-supplied answer_template.json. Use when a task asks for a production gap analysis, retention/litigation-hold gap review, cross-system remediation dashboard, or production-readiness review, and provides an answer_template.json plus a hub base URL and X-API-Key. Covers reading the contract, querying the hub, classifying material vs. non-material issues, computing privilege/QC metrics, and assembling one validated JSON object.4---56# Investigation Review Hub — production gap & remediation analysis78## What these tasks are910Outside counsel / legal-ops needs a **single structured JSON object** that turns11the state of one litigation matter into a gap-and-remediation deliverable:12material production gaps and defects, per-category coverage, retained/available13remediation sources, numeric privilege & QC metrics, and a prioritized action14plan with owners. The exact key names, enum vocabularies, metric list, and15ordering **change every task** — the only fixed input is the matter and the16`answer_template.json` you are handed. Never reuse another task's field names,17enum values, or numbers; derive them from *this* task's template and hub data.1819The Investigation Review Hub is the **sole source of business evidence**. The20task's local payload (`request_context.json` / `review_scope.json` /21`matter_context.json`) supplies only context: `matter_id`, client, category22codes/labels, API config, cutoff. Do **not** read environment source files,23database/seed files, generated manifests, hidden notes, or any answer/evaluation24file — event and source evidence must come from the hub.2526## Operating procedure27281. **Read the context payload** in `input/payloads/` — capture `matter_id`,29 client, category-code family, review cutoff, and any allowed/excluded-source30 notes. This tells you *which* matter and gives human-readable category labels.31322. **Read `input/payloads/answer_template.json` and treat it as the contract.**33 Extract, for this task specifically:34 - `required_top_level_keys` (the object's shape),35 - each list's `item_required_keys` and field types,36 - the `enums` / `enum_choices` (you MUST emit only these exact strings),37 - `ordering_rules` (how to sort each list), and38 - the `metrics` required keys with their precise definitions.39 The template *defines the schema; it never contains the answer.* See40 `references/output_contract.md` for the recurring 5-part archetype that these41 templates all instantiate under different names.42433. **Get network config from `environment_access.md`** (the only file to use for44 network access): the base URL (`GDPEVO_ENV_BASE_URL`), the `X-API-Key`45 header value, and the allowed endpoint list. Send the `X-API-Key` header on46 every request. Do not hardcode a base URL or key — read them each run.47484. **Pull matter-scoped evidence from the hub.** Confirm the matter via49 `GET /api/matters`, then read the evidence tables — always filtered to this50 `matter_id`. `GET` endpoints accept `?matter_id=<id>` (and other column51 filters) and return normalized arrays; `POST /api/query` runs read-only SQL52 (`{"sql": "..."}` → `{columns,row_count,rows,truncated}`) for joins and53 aggregation. Endpoint→table map, field semantics, and query recipes are in54 `references/hub_api.md`. Note `hold_date` from the matter — it is the pivot55 for retention classification.56575. **Classify each candidate into material findings vs. noise**, and map raw hub58 values to this template's enums, using `references/gap_classification.md`.59 Core judgments that recur:60 - **Pre-hold, policy-compliant destruction is NOT a preservation failure**61 (`event_date` < `hold_date` and within `retention_period_months`); only62 **post-hold loss** is spoliation to disclose.63 - Uncollected / partially collected personal or key sources = collection gap.64 - `retained` / available archives *limit irretrievable loss* for the65 categories they cover — list them as remediation sources.66 - Responsiveness miscoding → recode & produce; privilege **log gaps**67 (`withheld_count` > `logged_count`) → supplement log; **over-designation /68 miscoded privilege** → re-review/downgrade; **third-party** entries →69 waiver assessment; a zero-production claim contradicted by responsive docs70 → readiness blocker; `should_exist_missing` → locate missing record.71 - **Filter distractors:** routine QC (`metadata_gap`, `duplicate_overlay`),72 `issue_tags: routine`, and `*-NOISE-*` / sampling actions are not material73 unless the template's definitions pull them in.74756. **Compute metrics exactly as the template defines them**, as whole integers.76 Recurring identity: **`unlogged = withheld_count − logged_count`**. Honor77 scoping qualifiers in a metric's description (e.g. "from selected78 incomplete-log blockers only") rather than summing every row. Booleans like79 `production_ready`/`rolling_production_ready` are `true` only when no material80 blocker remains for any in-scope category.81827. **Use stable hub IDs verbatim** for every id/ref field — `event_id`,83 `source_id`, `finding_id`, `entry_id`, `action_id`, `doc_id`, and84 `category_code` exactly as returned. Never invent, renumber, or reformat IDs.85 Ref lists (`source_refs`, `issue_refs`, `blocking_refs`, `target_refs`,86 category sets) are sorted ascending.87888. **Build the action plan** from `remediation_actions` where they exist, mapping89 the hub's human-readable `owner` and `action_type` to the template's `owner`90 and `action_type` enums, and its `priority`/`severity` to the template's91 `priority` enum. Rank by severity/production impact with **1 = highest**; make92 each material finding traceable to an action and vice-versa.93949. **Assemble, order, and validate.** Include only material/non-complete items95 where the template scopes a list that way. Ensure every `required_top_level_key`96 is present, every `item_required_key` is present on every item (use `0` for97 N/A integers, `null` for N/A strings/dates), every enum value is legal, and98 every list obeys its `ordering_rules`. Cross-check that findings, category99 coverage, sources, metrics, and actions tell one consistent story.10010110. **Output exactly one JSON object and nothing else** — no prose, no code102 fences, no trailing commentary.103104## Guardrails105- Hub = evidence; payload = context/labels; nothing else is a source.106- The template is authoritative for names/enums/order/precision — re-read it per107 task; do not carry over vocabulary from a prior matter.108- Every hub read is filtered to the current `matter_id` (the hub holds many109 matters).110- Emit only enum strings that appear in *this* template; when unsure, pick the111 closest legal value and keep it consistent across sections.