Problem
AWF currently has two inconsistent schema versioning schemes:
- Config schema (
awf-config.v1.schema.json) — uses independent v1 versioning, published as a release asset
- 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:
- Build-time substitution: Read version from
package.json during npm run build
- Environment variable: Pass
AWF_VERSION to containers; token-tracker reads it at runtime
- 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.
Problem
AWF currently has two inconsistent schema versioning schemes:
awf-config.v1.schema.json) — uses independentv1versioning, published as a release assetaudit.v1.schema.json,token-usage.v1.schema.json) — use independentv1versioning, not published as release assetsThe
v1naming is confusing alongside repo release versions (e.g.v0.25.35). It is unclear whetherv1refers 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/v2version scheme. Schema files should be named without a version suffix — the repo release tag provides the version:schemas/audit.v1.schema.jsonschemas/audit.schema.jsonschemas/token-usage.v1.schema.jsonschemas/token-usage.schema.jsondocs/awf-config.v1.schema.jsondocs/awf-config.schema.json2. Update
_schemafield in JSONL records to use repo versionThe
_schemawire-format field in JSONL records should embed the repo version:"_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:
Download URLs would follow the pattern:
4. Embed version in schema
$idat release timeEach schema's
$idshould include the release tag, e.g.:The
generate-schema.mjsscript already does this for the config schema; extend the pattern to JSONL schemas.Files to Change
Schema files
schemas/audit.v1.schema.json→ rename toschemas/audit.schema.json; update$id, remove"version": "1", change_schemaconst to patternschemas/token-usage.v1.schema.json→ rename toschemas/token-usage.schema.json; update$id, remove"version": "1", change_schemaconst to patterndocs/awf-config.v1.schema.json→ rename todocs/awf-config.schema.jsonsrc/awf-config-schema.json→ may need corresponding renameschemas/README.md— update file references, versioning policy, examplesRecord writers (embed version at build/release time)
src/squid-config.ts— updateaudit_jsonllogformat_schemavaluecontainers/api-proxy/token-tracker.js— update_schemavalue inwriteTokenUsage()and WebSocket pathpackage.jsonor env var)Release workflow
.github/workflows/release.yml— copy JSONL schemas torelease/, add to upload list, generate versioned$idTests
src/squid-config.test.ts— update_schemaassertionscontainers/api-proxy/token-tracker.test.js— update_schemaassertions and validation testssrc/logs/log-parser.test.ts— update test fixtures with new_schemaformatsrc/schema.test.ts— update if config schema filename changesDocumentation
docs/releasing.md— update schema versioning section, add JSONL schema URLsschemas/README.md— update versioning policyDesign Considerations
Version injection for
_schemafieldThe
_schemavalue must match the repo version at release time. Options:package.jsonduringnpm run buildAWF_VERSIONto containers; token-tracker reads it at runtimesquid-config.tsalready has access to the version; inject into logformatOption 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 readpackage.jsonversion).Backward compatibility for log parsers
Existing parsers that check
_schema === "audit/v1"will need to handle the new format. The_schemafield should use a pattern likeaudit/v<semver>so parsers can use a prefix match (_schema.startsWith("audit/")) rather than exact match.Schema
_schemafield constraintChange from
"const": "audit/v1"to"pattern": "^audit/v\\d+\\.\\d+\\.\\d+$"to validate the new format while allowing any version.