Releases: blackwell-systems/gcf-typescript
Release list
v2.4.0: Graph delta decode + verify; session + conformance hardening
Fixes
- The conformance runner now hard-fails on any unhandled operation (instead of silently skipping it) and exercises session, delta, roundtrip, and pack-root fixtures end to end; the graph delta wire decode and verify path is now covered, so no operations remain allow-listed.
- Implemented the graph delta wire decoder and verifier (
decodeDelta/verifyDelta): parse aGCF profile=graph delta=truewire back into removed/added symbols and edge changes, apply them atomically to a base snapshot, recomputepack_root, and reject a wrongnew_rootwithroot_mismatch(SPEC 10.4). The## addedencoder now emits the trailingdistancefield (SPEC 3.4.1, Section 10.1). The sharedgraph-deltafixtures now run end to end: 001 (encode, gains the trailing distance), 002 (verified apply), 003 (root_mismatchrejection). - Session encoding correctness fix.
encodeWithSessionassigned per-response local IDs instead of stable session-global IDs, so the cross-call dedup references (@N # previously transmitted) pointed at the wrong symbols, and the header emitted zero-valuedbudget/tokens/edges. Both are fixed to match the reference; graph session output is now byte-identical across all six SDKs. This had gone undetected because the conformance runner skipped the shared graph-session fixtures (now wired). - Buffered graph encoder: order edges by source ID, then target ID, then edge type (SPEC 16.1), instead of emitting them in input order. Decode-invariant (edges are a set) and does not affect
pack_root(which sorts edge records independently), so no content addresses change. Pinned by shared fixturegraph-encode/003. Streaming edges remain in producer-arrival order. - Decoder: reject an orphan
.fieldattachment (a.fieldwhose name is neither a^-marked column of its row nor a>-containing field name, SPEC 7.4.6.1.4) instead of silently absorbing it as an undeclared extra field. Such a stray attachment previously decoded to a record no encoder produces, silently injecting a field onto the last-parsed row (a lossless round-trip hole); now rejected per SPEC 16.5 (orphan_attachment). - Decoder: reject an orphan positional inline body (a pipe-delimited line with no eligible
^{}attachment-marker cell) instead of silently dropping it. The object-body parser previously skipped any unrecognized line, so a stray positional body (e.g. a secondBob|b@t.comafter a row's one inline cell was filled) vanished with no error (silent data loss); now rejected per SPEC 16.5 (orphan_inline_attachment). - Graph streaming trailer: the edge count is now always the last
countsentry, even when the stream has no edges (positionalcounts=2,1,0; labeledcounts=…,edges:0). A zero-edge stream previously dropped it, violating the SPEC §8.4 / §8.4.1 rule that the edge count is always present and last (the invariant that keeps the positional form unambiguous). The graph trailer is decoder-ignored, so this changes producer output only.
Streaming: opt-in labeled trailer counts (SPEC §8.4.1)
- New
labeledTrailerCountsstream option onStreamEncoder. When set, the##! summarygraph streaming trailer emitscounts=in the labeled formlabel:countper group (e.g.counts=targets:2,related:1,edges:3) instead of the default positional values-only form (counts=2,1,3). Default false is byte-identical to prior output. - Opt-in and non-breaking: a producer-side comprehension aid for known weak consumers. The trailer counts remain informational (decoder-ignored) in both forms; neither changes the decoded payload. Mirrors the
gcf-goreference.
Conformance and docs
- Streaming graph trailer now emits
distance_Ngroup counts in pure group-header emission order (dropping a fixedtargets,related,extendedprefix), matching the other SDKs and deterministic per SPEC 16.1. Byte-identical for contract-conformant (ascending-distance) input; pinned by shared fixturesstreaming-v2/010–011. - The conformance runner now executes the
graph-stream-encodefixtures (streaming-encode parity, previously decode-only): fixture 004 (positional trailer) and 005 (labeled trailer). - README: corrected the streaming example trailer from the defunct
## _summary … sections=to the real##! summary … counts=; README now leads with the project diagram.
Full Changelog: v2.3.0...v2.4.0
v2.3.0
Generic-profile delta + re-anchor session helper (SPEC §10a)
Delta encoding comes to the generic profile — the multi-turn compression that JSON and TOON structurally lack — plus a producer-side re-anchor helper. Byte-for-byte interoperable across all six GCF SDKs (Go, Python, TypeScript, Rust, Swift, Kotlin) against a shared conformance suite.
Generic-profile delta (§10a)
Keyed row diffs: send only what changed (## added / ## changed / ## removed) instead of re-sending the whole table each turn.
GenericSet+GenericDeltaPayload;genericPackRoot(content-addressedgcf-pack-root-v1)diffGenericSets(producer) ·encodeGenericFull/encodeGenericDelta·decodeGenericFull/decodeGenericDelta·verifyGenericDelta(atomic apply +new_rootverification)- Opt-in and bilateral; the existing encode path is unchanged. Node-only (uses
crypto).
Re-anchor session helper (§10a.8)
GenericDeltaSession — a thin stateful producer that manages the re-anchor cadence for you. Each next() returns either a compact delta or, on its cadence, a full re-anchor, updating its held base.
fixedN(n)(default N=15) orsizeGuard()(size-adaptive, production-recommended)- No new wire syntax; cadence knobs are never wire fields, so the decoder stays cadence-agnostic. A schema change forces a full.
Why it matters
Across a 50-turn comprehension study, six of seven cleanly-measured models comprehend delta as well as full-resend at a fraction of the tokens; the one model that drifts at depth is closed by the re-anchor.
Correctness
Byte-for-byte identical wire and pack roots across all six SDKs, verified by shared conformance fixtures (generic-pack-root, generic-delta, generic-delta-session). Fuzzed: the decoder never crashes on arbitrary input and arbitrary string cells survive the round-trip with the pack root preserved. MIT, zero runtime dependencies. Ships with GCF SPEC v3.3.0.
Install: npm i @blackwell-systems/gcf
Adopted by
Headlined by Chrome DevTools MCP — the #1 most-starred MCP server on GitHub (46K★), built by the Google Chrome DevTools team, which merged GCF as an experimental data format (--experimentalDataFormat=gcf) after a 4-round review.
Also running in production across the ecosystem:
- OmniRoute (15.6K★) — AI gateway/proxy; GCF vendored into its compression engine
- Raycast (7.5K★) — JSON→GCF converter extension in the Store
- Speakeasy —
oq --format gcffor OpenAPI query output - NetClaw (556★) — network automation; switched from TOON to GCF
- ctx (510★) — Claude Code tool-recommender;
pip install "claude-ctx[gcf]" - bb — Bitbucket Cloud CLI/TUI;
--format gcf - NeuroNest — agent-first IDE
- Open Data Products SDK — Linux Foundation data-product toolkit
- knowing · agent-lsp — code-intelligence + LSP-orchestration MCP servers
Using GCF in production? Open an issue to be listed.
v2.2.3
Patch release: a losslessness fix in nested-object flattening and prototype-pollution hardening in the generic decoder. No API changes; recommended for all users.
🐛 Fixes
- Losslessness: null nested objects are no longer dropped. A nested object that was an object in some records and
nullat an intermediate level in others (e.g.{"meta": {"owner": null}}) was being flattened, and on decode thenullreconstructed as a missing key instead ofnull, silently losing data. Such fields now fall back to the attachment encoding, which round-trips exactly. A top-levelnullstill flattens (it emits-and rebuilds via the all-null rule), so compression is unaffected for that case.
🔒 Security (JS/TS only)
- The generic decoder no longer touches
Object.prototype. A__proto__path segment in hostile GCF could pollute the prototype, and keys shadowing built-ins (toString,constructor) were misparsed. All membership checks now useObject.prototype.hasOwnProperty.call; a sharedsafeAssignwrites a literal__proto__as an own property; unsafe path segments are dropped and non-object intermediates guarded. Keys namedtoString/constructor/valueOfnow round-trip correctly. (Map-based SDKs, Go/Python/Rust/Swift/Kotlin, are not affected by this class.)
✅ Tests
- Added
prototype_pollution.test.ts(nested/top-level__proto__, hostile path columns, built-in-named keys). - Extended the property-based round-trip fuzz to exercise the v3.2 flatten path with aligned nested objects and nulls at depth, the shape the prior scalar-only generator never produced. Verified failing on the pre-fix encoder and passing on the fix at 500k iterations.
The nested-null losslessness fix is format-level and ships in the Go/Python/Rust/Swift/Kotlin SDKs too; new shared conformance fixtures (flatten/017–019) lock it in across all implementations.
Full Changelog: v2.2.2...v2.2.3
v2.2.2
Build
- npm provenance attestations enabled (published from GitHub Actions with
--provenance) - Verifiable build origin: every release links to source commit and CI workflow
- Provenance verification: https://www.npmjs.com/package/@blackwell-systems/gcf#provenance
No API changes. Same encode/decode behavior as v2.2.1.
Full Changelog: v2.2.1...v2.2.2
v2.2.1
Flatten Opt-Out
encodeGeneric(data, { noFlatten: true })disables nested object flattening- Backward compatible:
encodeGeneric(data)unchanged
Bug Fixes
- Field names containing
>excluded from tabular columns (spec rule 7.4.6.1.4) - Field names containing
>no longer eligible for flattening analysis - Decoder no longer treats literal
>in key names as a path separator - Decoder accepts orphan attachments (fields excluded from column list)
- 200K round-trips (both modes, > in keys) zero failures; 12 targeted edge case tests
Full changelog: v2.2.0...v2.2.1
Full Changelog: v2.2.0...v2.2.1
v2.2.0: Nested Object Flattening (Spec v3.2)
Nested Object Flattening
Encoder automatically flattens fixed-shape nested objects into > path column names. Decoder reconstructs nesting from > paths.
- 20-48% fewer tokens on deeply nested API data
- 100% comprehension on every frontier model
- Zero regression on 200K random + adversarial round-trips
- Falls back to attachment mechanism for non-flattenable cases
Install: npm install @blackwell-systems/gcf@2.2.0
Full Changelog: v2.1.2...v2.2.0
v2.1.2
Patch release. Fixes encoder quoting for edge cases involving bracket-colon patterns in string values. 100M fuzz iterations, zero failures.
v2.1.1
CommonJS support
Added CommonJS bundle (dist/cjs/index.cjs) for compatibility with CJS environments like n8n, serverless runtimes, and older Node.js projects.
The exports map now includes both import (ESM) and require (CJS) conditions. No changes needed for existing ESM consumers.
This fixes: No "exports" main defined errors when using @blackwell-systems/gcf in CommonJS projects.
v2.1.0
Spec v3.1 Conformance
Spec change
toolfield in graph profile header is now optional (SHOULD be present for MCP, not required)
Bug fixes
- Quote strings containing commas in scalar values
- Decode v2-format indented attachments in tabular rows
- Reject duplicate attachments on the same row
- Reject orphan attachments on rows without
^cells
Conformance
- 157/157 fixtures passing
- 23.25B+ round-trips verified across all 6 implementations, zero failures
Full spec release: gcf v3.1.0
v2.0.2: Inline Schema Encoding
v2.0.2: Inline Schema Encoding
The generic profile encoder now produces inline schema format for nested objects with 3+ scalar fields.
Breaking Changes
encodeGenericoutput format changed (inline schemas, no attachment indentation)- Decoder no longer accepts v1.x indented attachment syntax
- Comma no longer quoted in pipe-delimited contexts (only in comma-delimited inline arrays)
- Strings starting with digits no longer quoted unless they match JSON number grammar
New Features
- Inline object schema (
^{fields}): nested objects encoded positionally - Shared array schemas: identical nested arrays omit field headers after first row
- Browser-safe entry point (
"browser"field in package.json): excludes Node-onlypackRoot/deltamodules - 25.5% fewer tokens than TOON across 15 real-world datasets
Integrity
- 141M lossless round-trip iterations
- 100% comprehension accuracy on every frontier model tested
- 156 conformance fixtures passing
Migration
- import { encodeGeneric } from '@blackwell-systems/gcf' // works in Node
+ import { encodeGeneric } from '@blackwell-systems/gcf' // works in Node AND browserpackRoot and encodeDelta are Node-only (require crypto). Import directly if needed:
import { packRoot } from '@blackwell-systems/gcf/dist/packroot.js'
import { encodeDelta } from '@blackwell-systems/gcf/dist/delta.js'Full spec: https://github.com/blackwell-systems/gcf/releases/tag/v3.0.0