# Validate Session Schemas

> Loop over recent local AI-coding session log files for every supported file-based platform (Copilot Chat, Copilot CLI, JetBrains, Claude Code, Gemini CLI, Antigravity, OpenCode) and validate they still match the documented schema, while surfacing newly-discovered fields we could start using. Use after an editor/CLI update, when adding a parser, or on a schedule to catch schema drift early.

- Skill: `rajbos/validate-session-schemas` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add rajbos/validate-session-schemas`
- Raw SKILL.md: https://api.skillmd.com/api/skills/rajbos/validate-session-schemas/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: rajbos (https://skillmd.com/u/rajbos)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/rajbos/validate-session-schemas

---


# Validate Session Schemas Skill

Validates that **recent** session log files on the current machine still match
the schema our parsers expect, **per supported platform**, and surfaces
**new fields** that appeared on disk but aren't documented/used yet.

It answers two questions in one pass:

1. **Did anything break?** — Drift detection against a small set of fields our
   parsers actually depend on ("contracts"). A missing required field on an
   observed record type is a `DRIFT` failure.
2. **Is there new information to use?** — Any field observed on disk that is not
   in the known baseline ("knownFields") is reported as a new field. These are
   candidates for new features or better token attribution (e.g. real token
   counts, new model metadata, new event types).

## Why this skill exists

The pre-existing `copilot-log-analysis` skill (`analyze-session-schema.ps1`)
only covered VS Code Copilot Chat JSON + Copilot CLI JSONL + OpenCode, with
crude substring-based "new field" detection. It did **not** loop per supported
platform, had no recency window, and didn't cover JetBrains, Claude Code,
Gemini CLI, or Antigravity. This skill closes that gap.

## Platforms covered

The source of truth for supported platforms is
`src/adapters/adapterRegistry.ts`. This skill validates the
**file-based JSON/JSONL** ecosystems that have schema docs under
`docs/logFilesSchema/`:

| Platform id    | Editor / tool        | Format | Discovery root |
|----------------|----------------------|--------|----------------|
| `copilot-chat` | VS Code Copilot Chat | json / jsonl | VS Code variants `workspaceStorage/*/chatSessions`, `globalStorage` |
| `copilot-cli`  | Copilot CLI          | jsonl  | `~/.copilot/session-state/` |
| `jetbrains`    | JetBrains Copilot    | jsonl  | `~/.copilot/jb/{uuid}/partition-*.jsonl` |
| `claude-code`  | Claude Code          | jsonl  | `~/.claude/projects/{hash}/*.jsonl` |
| `gemini-cli`   | Gemini CLI           | jsonl  | `~/.gemini/tmp/*/chats/session-*.jsonl` |
| `antigravity`  | Antigravity          | jsonl  | `~/.gemini/antigravity/brain/*/.system_generated/logs/transcript.jsonl` |
| `opencode`     | OpenCode             | json / jsonl | `<xdg-data>/opencode/storage/session/**/ses_*.json`; also `opencode.db` (SQLite, via `node:sqlite`) |

**Not validated by this skill** (DB / binary formats that need the adapters'
own parsers, so a generic JSON walker can't read them): `crush` (SQLite),
`visual-studio` (MessagePack), `continue`, `mistral-vibe`, `claude-desktop`.
They are listed in the report under "Not validated" so coverage is never
silently overstated. If you add a new file-based adapter, add a discovery
function + a `schema-baselines.json` entry here too.

## Usage

```bash
# Validate every platform's recent sessions (last 30 days, 5 files each)
node .github/skills/validate-session-schemas/validate-session-schemas.js

# Widen the window and look at more files
node .github/skills/validate-session-schemas/validate-session-schemas.js --days 60 --max 10

# One platform only
node .github/skills/validate-session-schemas/validate-session-schemas.js --platform claude-code

# Machine-readable output (for CI / further processing)
node .github/skills/validate-session-schemas/validate-session-schemas.js --json

# Refresh the "known fields" snapshot from what's on disk (does NOT touch contracts)
node .github/skills/validate-session-schemas/validate-session-schemas.js --update-baseline

# Include truncated example values (may contain user content — off by default)
node .github/skills/validate-session-schemas/validate-session-schemas.js --include-examples
```

### Options

| Flag | Meaning |
|------|---------|
| `--days N` | Only consider files modified within the last N days (default 30; `0` = no limit) |
| `--max N` | Analyze at most N most-recent files per platform (default 5) |
| `--platform <id>` | Validate a single platform |
| `--update-baseline` | Rewrite `knownFields` from observed fields; never modifies `contracts` |
| `--include-examples` | Capture truncated example values per field |
| `--fail-on-new-fields` | Exit non-zero when new fields are discovered |
| `--json` | Emit JSON only |
| `--help` | Usage |

### Exit codes

- `0` — all observed contracts pass (new fields alone do not fail unless `--fail-on-new-fields`)
- `1` — contract drift or an unparseable file
- `2` — configuration / environment error (bad args, missing baseline)

### Per-platform statuses

`PASS`, `DRIFT`, `NO_FILES` (editor not installed / no sessions),
`NO_RECENT_FILES` (sessions exist but none in the window), `INCONCLUSIVE`
(recent files existed but no parseable records).

## How drift and new-field detection work

`schema-baselines.json` holds two independent things per platform:

- **`contracts`** — hand-maintained list of the fields our parsers depend on,
  optionally scoped by `format` (`json`/`jsonl`) and a `discriminator`
  (the JSONL event `type` / `kind`). A contract is only evaluated when matching
  records are actually observed, so a union format never produces false drift
  for an event type that simply wasn't present. `--update-baseline` never
  changes contracts — edit them by hand when the parser's real dependencies
  change.
- **`knownFields`** — the last-known set of observed field paths. New = observed
  − known. Refresh with `--update-baseline` once you've reviewed and accepted
  the new fields.

Field-path notation: `a.b` nested, `arr[]` array items, `arr[].c` a field inside
array items.

## Acting on results

- **DRIFT** → a required field disappeared. Open the platform's doc under
  `docs/logFilesSchema/` and the matching adapter under
  `src/adapters/`, confirm the change, and update both the
  parser and the contract.
- **New fields** → review them. If useful (e.g. real token counts, new model
  metadata, a new event type), document them in `docs/logFilesSchema/`, consider
  wiring them into the adapter/parser, then run `--update-baseline` to clear them
  from future reports.

## Periodic run (optional)

This script is dependency-free Node and CI-friendly via its exit codes:

```yaml
- name: Validate recent session schemas
  run: node .github/skills/validate-session-schemas/validate-session-schemas.js --json
```

(On CI the runner usually has no local session files, so most platforms report
`NO_FILES` and the job passes — it's most useful run on a developer machine or a
self-hosted runner that has real session data.)

## Related

- `docs/logFilesSchema/` — per-platform schema documentation (the human source of truth)
- `.github/skills/copilot-log-analysis/` — deeper Copilot-only schema field dump (`analyze-session-schema.ps1`)
- `.github/skills/validate-app-db-schema/` — validates the unrelated `~/.copilot/data.db` hierarchy schema
- `src/adapters/adapterRegistry.ts` — canonical list of supported ecosystems

