# VettedHaul Evidence Pack Spec v1.0

**Spec version:** 1.0.0
**Spec URL:** https://vettedhaul.com/specs/evidence-pack/v1.0
**Status:** draft
**Last updated:** 2026-05-21
**Editor:** Tom Pinder, VettedHaul (Startvest LLC)

---

## What this spec is

The Evidence Pack is the artifact VettedHaul produces for a single carrier
vetting event. One artifact per booking decision. The pack is what gets
handed to defense counsel the day a demand letter arrives.

This document specifies the structure, content, and admissibility
guarantees of that artifact. v1.0 is opinionated and minimal. Later
versions extend; they do not remove fields.

## Why an opinionated spec instead of customer-by-customer

Schema-by-committee produces ten incompatible packs that no carrier
discovery process can compare against each other. A single versioned spec
produces packs that defense counsel can read on sight, that insurance
underwriters can validate against a checklist, and that opposing counsel
cannot dismiss as ad-hoc.

The spec is grounded in three convergent constraints:

1. **The Montgomery v. Caribe Transport II standard.** State-law
   negligent-hiring claims now proceed against brokers on the merits. The
   merits turn on what the broker checked at the moment of booking and
   what the broker can produce in discovery.
2. **The FMCSA four-check baseline.** Safety rating, CSA scores (across
   the seven BASIC categories), certificate of insurance, and operating
   authority status are the four data points FMCSA itself publishes and
   the four points industry convention treats as the floor.
3. **Federal Rules of Evidence 901/902 + 803(6).** For the pack to be
   admissible as a business record, it must be authenticatable, the
   custodian must be identifiable, and the record must be made
   contemporaneously with the event.

Everything in the schema below ties back to one of those three sources.

---

## Document anatomy

An Evidence Pack v1.0 is a single logical document with five sections.
It is exported as a paired PDF + JSON artifact. The JSON is the canonical
form; the PDF is a deterministic render of the JSON.

```
1. Pack Identity         (who/what/when of the capture)
2. Subject               (the carrier being vetted)
3. Four Checks           (rating + CSA + insurance + authority)
4. Decision              (the booking action and rationale)
5. Authentication        (hash, timestamp, custodian attestation)
```

Optional sixth section for Defender-tier monitoring:

```
6. Continuous Monitoring (delta events post-decision)
```

---

## 1. Pack Identity

Captures who created the pack, when, and on whose behalf. Required for
FRE 803(6) custodian identification.

| Field | Type | Required | Notes |
|---|---|---|---|
| `spec_version` | string | yes | Must equal `1.0.0`. |
| `spec_url` | string (URL) | yes | Resolves to this document. |
| `pack_id` | UUID v4 | yes | Globally unique pack identifier. |
| `captured_at` | ISO-8601 with timezone | yes | Wall-clock time of capture. |
| `captured_by` | object | yes | See below. |
| `workspace_id` | UUID | yes | VettedHaul workspace (brokerage). |
| `workspace_legal_name` | string | yes | Legal entity name of the brokerage. |
| `workspace_usdot` | string | yes | Brokerage's own USDOT/MC number. |

`captured_by` object:

| Field | Type | Required | Notes |
|---|---|---|---|
| `user_id` | UUID | yes | VettedHaul user ID. |
| `user_email` | string | yes | Email of the capturing user. |
| `user_role` | string | yes | `dispatcher`, `broker`, `admin`, etc. |
| `client_ip` | string | yes | IP address at capture time, for chain-of-custody. |
| `user_agent` | string | yes | Browser/client identifier. |

## 2. Subject

The carrier being vetted. Pulled from FMCSA SAFER + the broker's input.

| Field | Type | Required | Notes |
|---|---|---|---|
| `usdot_number` | string | yes | Primary FMCSA identifier. |
| `mc_number` | string | conditional | Required if carrier holds motor carrier authority. |
| `legal_name` | string | yes | As filed with FMCSA. |
| `dba_name` | string | optional | Doing-business-as, if any. |
| `physical_address` | object | yes | `street`, `city`, `state`, `zip`, `country`. |
| `mailing_address` | object | optional | Same shape if different from physical. |
| `entity_type` | string | yes | `Carrier`, `Carrier/Broker`, `Broker`, `Freight Forwarder`. |
| `operation_classification` | string[] | yes | Authorized For Hire, Interstate, Hazmat, etc. |
| `power_units` | integer | optional | Self-reported by carrier; from MCS-150. |
| `drivers` | integer | optional | Self-reported by carrier; from MCS-150. |

## 3. Four Checks

The four data captures that satisfy the FMCSA-baseline negligent-hiring
defense. Each check carries its own source URL, fetched-at timestamp, and
response hash so the underlying data can be re-fetched and re-verified in
discovery.

### 3a. Safety Rating Snapshot

Source: FMCSA SAFER (`https://safer.fmcsa.dot.gov`).

| Field | Type | Required | Notes |
|---|---|---|---|
| `rating` | enum | yes | `Satisfactory`, `Conditional`, `Unsatisfactory`, `Unrated`, `None`. |
| `rating_date` | ISO-8601 date | conditional | Required when `rating` is not `Unrated`/`None`. |
| `last_review_date` | ISO-8601 date | optional | Most recent compliance review. |
| `source_url` | string (URL) | yes | Exact URL fetched. |
| `source_fetched_at` | ISO-8601 datetime | yes | When VettedHaul retrieved the data. |
| `source_response_hash` | string (SHA-256) | yes | Hash of the raw upstream response body. |
| `source_response_archive_url` | string (URL) | optional | VettedHaul-hosted archive of the raw response. |

### 3b. CSA Scores Snapshot

Source: FMCSA SMS (`https://ai.fmcsa.dot.gov/SMS`). All seven BASIC
categories captured in a single snapshot. A carrier missing any category
is still captured with a `null` percentile and a `data_insufficient`
flag.

| Field | Type | Required | Notes |
|---|---|---|---|
| `sms_data_date` | ISO-8601 date | yes | The SMS "data through" date. |
| `categories` | object[] | yes | Seven entries. See below. |
| `source_url` | string (URL) | yes | Exact URL fetched. |
| `source_fetched_at` | ISO-8601 datetime | yes | When VettedHaul retrieved the data. |
| `source_response_hash` | string (SHA-256) | yes | Hash of raw response. |
| `source_response_archive_url` | string (URL) | optional | Archived raw response. |

Each `categories[i]` object:

| Field | Type | Required | Notes |
|---|---|---|---|
| `basic` | enum | yes | `UnsafeDriving`, `HoursOfService`, `DriverFitness`, `ControlledSubstances`, `VehicleMaintenance`, `HazmatCompliance`, `CrashIndicator`. |
| `percentile` | number or null | yes | 0-100; `null` if data insufficient. |
| `threshold` | number | yes | Alert threshold for this BASIC. |
| `alert_status` | enum | yes | `OverThreshold`, `UnderThreshold`, `NoData`. |
| `measure_value` | number or null | optional | Raw measure value. |
| `data_insufficient` | boolean | yes | `true` if FMCSA reports insufficient data. |

### 3c. Insurance Snapshot

Two-source check. (1) Carrier-supplied certificate of insurance (parsed
PDF) and (2) FMCSA L&I database (insurance on file). Concur or diverge.

| Field | Type | Required | Notes |
|---|---|---|---|
| `coi_pdf_hash` | string (SHA-256) | yes | Hash of the COI PDF received. |
| `coi_pdf_archive_url` | string (URL) | yes | VettedHaul-hosted immutable archive of the PDF. |
| `coi_parsed_at` | ISO-8601 datetime | yes | When VettedHaul extracted fields. |
| `coi_parser_version` | string | yes | E.g. `vh-coi-parser@1.0.0`. |
| `coi_parser_confidence` | number | yes | 0-1.0. Below 0.85 forces human review. |
| `liability_carrier` | string | yes | Insurance company name on the COI. |
| `liability_policy_number` | string | yes | As shown on the COI. |
| `liability_each_occurrence` | integer (USD) | yes | Single-occurrence limit. |
| `liability_aggregate` | integer (USD) | optional | Aggregate limit, if shown. |
| `liability_effective_date` | ISO-8601 date | yes | Per the COI. |
| `liability_expiration_date` | ISO-8601 date | yes | Per the COI. |
| `cargo_carrier` | string | conditional | If cargo coverage listed. |
| `cargo_limit` | integer (USD) | conditional | If cargo coverage listed. |
| `certificate_holder` | string | yes | The broker named on the COI. |
| `issuer_name` | string | yes | Agent/broker who issued the certificate. |
| `issuer_address` | string | optional | Issuer mailing address. |
| `fmcsa_li_concur` | enum | yes | `Concur`, `Diverge`, `LIDataMissing`. |
| `fmcsa_li_carrier` | string | conditional | Required when `fmcsa_li_concur` != `LIDataMissing`. |
| `fmcsa_li_policy_number` | string | conditional | As on FMCSA L&I. |
| `fmcsa_li_effective_date` | ISO-8601 date | conditional | As on FMCSA L&I. |
| `fmcsa_li_source_url` | string (URL) | yes | Exact L&I URL fetched. |
| `fmcsa_li_fetched_at` | ISO-8601 datetime | yes | When VettedHaul fetched L&I. |
| `fmcsa_li_response_hash` | string (SHA-256) | yes | Hash of L&I response. |
| `fmcsa_li_response_archive_url` | string (URL) | optional | Archived L&I response. |

A `Diverge` result is a flag, not a fail. Documentation of the divergence
is part of the defense; ignoring the COI in favor of L&I is a separate
operational policy.

### 3d. Operating Authority Snapshot

Source: FMCSA L&I (`https://li-public.fmcsa.dot.gov`).

| Field | Type | Required | Notes |
|---|---|---|---|
| `authority_type` | string[] | yes | `MotorCarrierProperty`, `MotorCarrierHHG`, `MotorCarrierPassenger`, `Broker`, `FreightForwarder`. |
| `authority_status` | enum | yes | `Active`, `Inactive`, `NotAuthorized`, `RevokedPending`. |
| `authority_grant_date` | ISO-8601 date | conditional | When status is `Active`. |
| `bond_or_trust_on_file` | boolean | conditional | Required for `Broker` authority. |
| `bond_amount` | integer (USD) | conditional | If `bond_or_trust_on_file`. |
| `source_url` | string (URL) | yes | Exact L&I URL fetched. |
| `source_fetched_at` | ISO-8601 datetime | yes | When VettedHaul retrieved the data. |
| `source_response_hash` | string (SHA-256) | yes | Hash of raw response. |
| `source_response_archive_url` | string (URL) | optional | Archived raw response. |

## 4. Decision

What the broker did with the four checks. The decision is the act the
litigation will turn on.

| Field | Type | Required | Notes |
|---|---|---|---|
| `decision` | enum | yes | `Booked`, `Rejected`, `MonitorOnly`. |
| `decision_at` | ISO-8601 datetime | yes | Wall-clock at the decision moment. |
| `decision_by` | object | yes | Same shape as `captured_by`. |
| `decision_rationale` | string | conditional | Required when `decision` is `Rejected`. Free text. |
| `load_reference` | string | optional | The broker's internal load/booking ID. |
| `shipper_reference` | string | optional | Shipper name or reference, if disclosable. |
| `decision_policy_ref` | string | optional | Reference to the brokerage's written vetting policy. |

## 5. Authentication

Three layers: hash of the canonical JSON, RFC 3161 trusted timestamp,
and a custodian attestation statement. Maps to FRE 901 (authenticity),
FRE 902(11)/(12) (self-authenticating business records), and FRE 803(6)
(records of regularly conducted activity).

| Field | Type | Required | Notes |
|---|---|---|---|
| `canonical_json_hash` | string (SHA-256) | yes | Hash of the deterministically-serialized JSON of sections 1-4 (and 6 if present). |
| `hash_algorithm` | string | yes | `SHA-256` for v1.0. |
| `serialization_spec` | string | yes | `RFC8785` (JCS canonicalization). |
| `rfc3161_timestamp` | object | yes | See below. |
| `signature` | object | optional | Ed25519 signature; required in v1.1. |
| `custodian_attestation` | object | yes | See below. |
| `chain_of_custody` | object[] | yes | Append-only event log. See below. |

`rfc3161_timestamp`:

| Field | Type | Required | Notes |
|---|---|---|---|
| `tsa_url` | string (URL) | yes | Trusted Timestamp Authority used. |
| `token` | string (base64) | yes | The RFC 3161 timestamp token. |
| `token_hash` | string (SHA-256) | yes | Hash of the token, for inclusion in the pack hash. |
| `obtained_at` | ISO-8601 datetime | yes | When the TSA token was acquired. |

`custodian_attestation`:

| Field | Type | Required | Notes |
|---|---|---|---|
| `attestation_text` | string | yes | Boilerplate business-records statement (template below). |
| `custodian_name` | string | yes | Legal name of the custodian (brokerage operator). |
| `custodian_title` | string | yes | Role within the brokerage. |
| `custodian_signed_at` | ISO-8601 datetime | yes | When the attestation was acknowledged. |
| `custodian_signature_method` | enum | yes | `ClickThrough`, `Wet`, `DigitalCertificate`. |

`chain_of_custody[i]`:

| Field | Type | Required | Notes |
|---|---|---|---|
| `event` | enum | yes | `Created`, `Sealed`, `Exported`, `MonitorEvent`, `Amended`. |
| `at` | ISO-8601 datetime | yes | When the event occurred. |
| `by` | string (user_id) | yes | Actor. |
| `note` | string | optional | Human-readable detail. |
| `prior_hash` | string (SHA-256) | conditional | Hash of the prior chain entry, forming the chain. |
| `entry_hash` | string (SHA-256) | yes | Hash of this entry. |

### Default custodian attestation text

> I, the undersigned, am the custodian of business records for
> [WORKSPACE_LEGAL_NAME]. The information contained in this Evidence
> Pack was recorded at or near the time of the events described, by a
> person with knowledge of those events, in the regular course of the
> brokerage's vetting activity. Records of this kind are kept in the
> regular course of business. The Evidence Pack and its constituent
> data captures have not been altered since the time stamps recorded
> herein.

## 6. Continuous Monitoring (Defender tier)

Optional section. Present when the pack covers a load with continuous
monitoring through delivery.

| Field | Type | Required | Notes |
|---|---|---|---|
| `monitor_started_at` | ISO-8601 datetime | yes | When monitoring began. |
| `monitor_ended_at` | ISO-8601 datetime | conditional | Required if monitoring closed. |
| `monitor_check_interval` | string | yes | E.g. `PT6H` (ISO-8601 duration). |
| `events` | object[] | yes | Delta events; see below. May be empty array. |

Each `events[i]`:

| Field | Type | Required | Notes |
|---|---|---|---|
| `at` | ISO-8601 datetime | yes | When VettedHaul observed the delta. |
| `delta_type` | enum | yes | `RatingChanged`, `CSAAlertEntered`, `CSAAlertExited`, `AuthoritySuspended`, `InsuranceLapsed`, `OutOfService`. |
| `before` | object | yes | Snapshot fragment of the prior state. |
| `after` | object | yes | Snapshot fragment of the new state. |
| `source_response_hash` | string (SHA-256) | yes | Hash of the upstream response that produced this delta. |
| `notified` | object[] | yes | Who/when was notified within VettedHaul. |

---

## Canonical serialization

The JSON is serialized using RFC 8785 (JSON Canonicalization Scheme):
- Object keys in lexicographic order.
- No insignificant whitespace.
- Numbers as the shortest exact decimal representation.
- UTF-8 throughout.

The `canonical_json_hash` covers sections 1-4 (and 6 if present), with
section 5 hashes computed last so they can reference the prior hashes.

## Export envelope

Each Evidence Pack exports as a pair:

- `vettedhaul-pack-<pack_id>.json` — canonical JSON.
- `vettedhaul-pack-<pack_id>.pdf` — deterministic PDF render of the JSON.

The PDF includes:
- Cover page: pack ID, capture timestamp, custodian, subject carrier.
- Sections 1-6 rendered in document order with the same table structure.
- A final page reproducing `canonical_json_hash`, the RFC 3161 token
  hash, and a human-readable verification instruction: how to re-hash
  the JSON and confirm a match.

PDF renderer is versioned (`pdf_renderer_version`) and the renderer
output is deterministic for a given JSON input. Two renders of the same
pack at different times produce byte-identical PDFs.

## Compatibility, versioning, deprecation

- The spec version follows semver. Field additions are minor (1.x).
  Field removals or semantic changes are major (2.x).
- A v1.0 pack is forward-compatible with v1.x readers.
- VettedHaul retains historical renderers so a v1.0 pack rendered today
  can be re-rendered byte-identically in 7 years (the retention floor).
- Deprecated fields stay in the schema with a `deprecated: true` flag in
  the spec; they are not removed mid-major.

## Open items for v1.1

These are deliberately deferred to keep v1.0 shippable:

- Ed25519 signature (required in v1.1; optional in v1.0).
- Multi-custodian co-attestation (when two parties sign the same pack).
- Schema for TMS-integrated booking references (Defender Pro tier).
- Schema for non-US-domiciled carriers (Mexican, Canadian cross-border).

## License

This spec is published under CC-BY 4.0. The schema is freely
implementable. Use of the "VettedHaul Evidence Pack" name requires a
conformance test pass; non-conforming implementations may use the
schema but not the name.

## Changelog

- **2026-05-21 - v1.0.0 (draft).** Initial publication. Five required
  sections + optional Continuous Monitoring. RFC 3161 timestamp
  required. Ed25519 signature deferred to v1.1.
