Skip to content

Unify schema versioning: use repo release version for all schemas and publish JSONL schemas as release assets #2397

Description

@lpcox

Problem

AWF currently has two inconsistent schema versioning schemes:

  1. Config schema (awf-config.v1.schema.json) — uses independent v1 versioning, published as a release asset
  2. JSONL schemas (audit.v1.schema.json, token-usage.v1.schema.json) — use independent v1 versioning, not published as release assets

The v1 naming is confusing alongside repo release versions (e.g. v0.25.35). It is unclear whether v1 refers to a schema format version, a major version, or something else. External consumers (like the gh-aw compiler) cannot easily pin to a specific release's schema.

Additionally, the JSONL schemas have no release download URLs, so consumers must reference raw git URLs which are less stable and not tied to a specific release.

Proposed Changes

1. Rename all schema files to use repo version

Drop the independent v1/v2 version scheme. Schema files should be named without a version suffix — the repo release tag provides the version:

Current New
schemas/audit.v1.schema.json schemas/audit.schema.json
schemas/token-usage.v1.schema.json schemas/token-usage.schema.json
docs/awf-config.v1.schema.json docs/awf-config.schema.json

2. Update _schema field in JSONL records to use repo version

The _schema wire-format field in JSONL records should embed the repo version:

Current New (example for v0.26.0)
"_schema": "audit/v1" "_schema": "audit/v0.26.0"
"_schema": "token-usage/v1" "_schema": "token-usage/v0.26.0"

This allows consumers to know exactly which AWF version produced the records and parse them with the correct schema.

3. Publish all schemas as release assets

Every release should upload all three schemas:

release/awf-config.schema.json       # config schema
release/audit.schema.json            # audit JSONL schema
release/token-usage.schema.json      # token-usage JSONL schema

Download URLs would follow the pattern:

https://github.com/github/gh-aw-firewall/releases/download/<tag>/awf-config.schema.json
https://github.com/github/gh-aw-firewall/releases/download/<tag>/audit.schema.json
https://github.com/github/gh-aw-firewall/releases/download/<tag>/token-usage.schema.json

4. Embed version in schema $id at release time

Each schema's $id should include the release tag, e.g.:

"$id": "https://github.com/github/gh-aw-firewall/releases/download/v0.26.0/audit.schema.json"

The generate-schema.mjs script already does this for the config schema; extend the pattern to JSONL schemas.

Files to Change

Schema files

  • schemas/audit.v1.schema.json → rename to schemas/audit.schema.json; update $id, remove "version": "1", change _schema const to pattern
  • schemas/token-usage.v1.schema.json → rename to schemas/token-usage.schema.json; update $id, remove "version": "1", change _schema const to pattern
  • docs/awf-config.v1.schema.json → rename to docs/awf-config.schema.json
  • src/awf-config-schema.json → may need corresponding rename
  • schemas/README.md — update file references, versioning policy, examples

Record writers (embed version at build/release time)

  • src/squid-config.ts — update audit_jsonl logformat _schema value
  • containers/api-proxy/token-tracker.js — update _schema value in writeTokenUsage() and WebSocket path
  • Need a mechanism to inject the current version into these at build time (e.g., read from package.json or env var)

Release workflow

  • .github/workflows/release.yml — copy JSONL schemas to release/, add to upload list, generate versioned $id

Tests

  • src/squid-config.test.ts — update _schema assertions
  • containers/api-proxy/token-tracker.test.js — update _schema assertions and validation tests
  • src/logs/log-parser.test.ts — update test fixtures with new _schema format
  • src/schema.test.ts — update if config schema filename changes

Documentation

  • docs/releasing.md — update schema versioning section, add JSONL schema URLs
  • schemas/README.md — update versioning policy

Design Considerations

Version injection for _schema field

The _schema value must match the repo version at release time. Options:

  1. Build-time substitution: Read version from package.json during npm run build
  2. Environment variable: Pass AWF_VERSION to containers; token-tracker reads it at runtime
  3. Squid config generation: squid-config.ts already has access to the version; inject into logformat

Option 1 is simplest for the Node.js code. Option 2 is needed for the Squid logformat since it is generated at runtime by squid-config.ts (which can read package.json version).

Backward compatibility for log parsers

Existing parsers that check _schema === "audit/v1" will need to handle the new format. The _schema field should use a pattern like audit/v<semver> so parsers can use a prefix match (_schema.startsWith("audit/")) rather than exact match.

Schema _schema field constraint

Change from "const": "audit/v1" to "pattern": "^audit/v\\d+\\.\\d+\\.\\d+$" to validate the new format while allowing any version.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions