Skip to content

factual-event-table

Extract every factual event from source documents into a Date/Time | Actor | Action | Detail | Source table — one row per discrete event, active voice with actor as grammatical subject, [not stated] for gaps, assertion attribution, no strategy or legal conclusions, dedup after extraction. Use when asked to extract events, build a chronology table, list what happened from emails, bundles, or productions.

Source: .opencode/skills/factual-event-table/SKILL.md — site rebuilt 2026-09-05.


Factual Event Table

Extract every factual event from the source document(s) into a table. Output is the table only.

Output columns (exact)

Date/Time | Actor | Action | Detail | Source

No summarizing sentences, headers, or narrative connective text between rows. One row per event, nothing else.

When to use

  • Asked to extract factual events, build an event table, or list what happened from emails, bundles, productions, reports, or a matter file.
  • Building the factual base for a chronology, submission, or proof.

When not to use

  • Legal analysis, liability characterisation, tactical reasoning, or draft argument — excluded by rule, not extracted.
  • Summaries or narratives — this skill produces rows only, never prose connective.

Row discipline

  1. One row per discrete event. Do not merge multiple actions into one row, even if they occur in the same email or document. Split them.
  2. Active voice only. See Active Voice Gate below. No exceptions.
  3. No adjectives or adverbs unless the word restates a specific value already present in the source (a date, a sum, a named defect, a defined term). Do not use words like "significant," "urgent," "clearly," "reasonable," "appropriately" unless quoting the source's own defined usage.
  4. Who/where/how/when, where available. For each event state the acting party, the location (if relevant), the method (email/call/letter/meeting/etc.), and the date/time. If any element is not present in the source, write exactly [not stated] — do not omit the column silently and do not approximate or infer a value.
  5. Distinguish established fact from asserted/contested claim. If the source records a party's assertion rather than a verified event (e.g. "X alleges," "X claims," "X states"), the Action column must include the attribution verb (alleges/states/claims) — never convert a party's assertion into an unqualified fact.
  6. Exclude legal conclusions and internal strategy/work product. Do not extract: characterizations of liability ("this constitutes a breach"), tactical reasoning, draft arguments, or analysis about how to present the case. If a passage is strategy rather than a fact about the dispute, exclude the row entirely — do not force it into the table.
  7. Source column cites the exact document, sender, and date/time the fact is drawn from — never "per the file" or similar vague attribution.
  8. Do not invent, round, or estimate any value. If a number, date, or name is ambiguous or illegible in the source, mark it [not stated] rather than supplying a best guess.
  9. Process the full document set before returning output. If the set is too large for one pass, process and return in sequential batches by date range, maintaining the same column structure and row discipline in each batch.

Active Voice Gate

Every Action cell must have the acting party as the grammatical subject performing the verb — never the recipient of the action as subject.

Passive (reject) Active (correct)
"The letter was sent to the Council" "Gavin McAuley sent the letter to the Council"
"The delay was caused by adverse conditions" "Adverse ground conditions caused the delay"
"Payment was withheld" "Liddell withheld payment"
"The drawing was revised" "Clyde Design Partnership revised the drawing"

Test: point to who is doing the verb, sitting before it in the sentence. If the sentence would still make sense with "by [nobody in particular]" tacked on the end, it is passive and must be rewritten.

Where the source itself is written passively (engineering reports, standard-form drainage comments saying "the specification should be amended" or "materials are required to comply"), identify and name the actual responsible party from context (e.g. "Clyde Design Partnership must amend the specification") — do not carry the source's passive construction into the table. If the actor genuinely cannot be determined from the source, use [not stated] rather than defaulting to a passive sentence to dodge the naming requirement.

Deduplication: after extraction, never before

Do not deduplicate emails before extraction. A forward is a distinct event, not noise — e.g. the timing of who-knew-what (was Anthony aware of X before he advised Y) depends on the forward's own timestamp and actor.

Stage What happens
1. Extract all Every email/document → row(s), no filtering. Includes forwards. Tag each by its actual timestamp and actor.
2. Flag identical Detail text Mechanical check — same content appearing under different source/actor/date.
3. Keep both, link them Original event row stands; forward row stands separately as transmission of that fact (e.g. Detail: "Reuben forwarded Gavin's email of [date] to Anthony"), never merged into one row.
4. Merge only true duplicates Same actor, same timestamp, literally the same email captured twice in the source. No informational loss. These alone collapse.

If volume threatens the pass, fix it by batching (rule 9), not by pre-dedup.

Self-check before returning

  • Every Action cell: actor named before the verb, active voice, attribution verb present where the source asserts rather than establishes.
  • Every gap: [not stated], never blank, never inferred.
  • Every Source cell: exact document + sender + date/time.
  • No adjectives/adverbs beyond source values. No liability labels. No strategy rows. No merged rows.
  • Table only.