Skip to content

Releases: blackwell-systems/gcf-python

v2.4.0: Graph delta decode + verify; session + conformance hardening

Choose a tag to compare

@blackwell-systems blackwell-systems released this 13 Jul 05:25

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 (decode_delta / verify_delta): parse a GCF profile=graph delta=true wire back into removed/added symbols and edge changes, apply them atomically to a base snapshot, recompute pack_root, and reject a wrong new_root with root_mismatch (SPEC 10.4). The ## added encoder now emits the trailing distance field (SPEC 3.4.1, Section 10.1). The shared graph-delta fixtures now run end to end: 001 (encode, gains the trailing distance), 002 (verified apply), 003 (root_mismatch rejection).
  • Session encoding correctness fix. encode_with_session assigned 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-valued budget/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).
  • Added the graph-profile PackRoot (pack_root(symbols, edges), gcf-pack-root-v1, SPEC 10.2): the content-addressed sha256 over canonical, independently-sorted symbol/edge records, byte-identical to gcf-go/rust/typescript/swift/kotlin. The conformance runner now exercises the shared graph-pack-root fixtures, which it had been skipping (so this primitive was previously unimplemented and untested).
  • Buffered graph encoder now matches the reference byte-for-byte: symbols are ordered by distance then descending score with local IDs assigned in output order, and the header omits budget/tokens/edges when zero (previously symbols kept input order and zero-valued header fields were always emitted). The conformance runner now exercises the shared graph-encode fixtures (001-003), which it had been skipping - which is how this divergence went uncaught.
  • 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 fixture graph-encode/003. Streaming edges remain in producer-arrival order.
  • Decoder: reject an orphan .field attachment (a .field whose 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 second Bob|b@t.com after 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 counts entry, even when the stream has no edges (positional counts=2,1,0; labeled counts=…,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 labeled_trailer_counts keyword on StreamEncoder. When set, the ##! summary graph streaming trailer emits counts= in the labeled form label:count per 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-go reference.

Conformance and docs

  • Streaming graph trailer now emits distance_N group counts in pure group-header emission order (dropping a fixed targets,related,extended prefix), matching the other SDKs and deterministic per SPEC 16.1. Byte-identical for contract-conformant (ascending-distance) input; pinned by shared fixtures streaming-v2/010011.
  • The conformance runner now executes the graph-stream-encode fixtures (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.
  • Added a generic-delta fuzz test (decoder never crashes; string round-trip).

Full Changelog: v2.3.0...v2.4.0

v2.3.0

Choose a tag to compare

@github-actions github-actions released this 12 Jul 16:12

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; generic_pack_root (content-addressed gcf-pack-root-v1)
  • diff_generic_sets (producer) · encode_generic_full / encode_generic_delta · decode_generic_full / decode_generic_delta · verify_generic_delta (atomic apply + new_root verification)
  • Opt-in and bilateral; the existing encode path is unchanged.

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.

  • fixed_n(n) (default N=15) or size_guard() (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). MIT, zero runtime dependencies. Ships with GCF SPEC v3.3.0.

Install: pip install gcf-python


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
  • Speakeasyoq --format gcf for 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.2

Choose a tag to compare

@github-actions github-actions released this 11 Jul 03:13

Patch release: a losslessness fix in nested-object flattening. 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 null at an intermediate level in others (e.g. {"meta": {"owner": null}}) was being flattened, and on decode the null reconstructed as a missing key instead of null, silently losing data. Such fields now fall back to the attachment encoding, which round-trips exactly. A top-level null still flattens (it emits - and rebuilds via the all-null rule), so compression is unaffected for that case.

✅ Tests

  • Added test_flatten_roundtrip: aligned arrays whose shared fields are fixed-shape nested objects with a field or an intermediate level sometimes null/absent, the shape the prior scalar-only generator never produced. Verified failing on the pre-fix encoder and passing on the fix at 500k iterations.

This is a format-level bug, fixed identically across the GCF SDKs (TypeScript / Go / Python / Rust / Swift / Kotlin); it is locked in by shared conformance fixtures (flatten/017019) that this SDK's conformance suite runs against the gcf spec repo.

Full Changelog: v2.2.1...v2.2.2

v2.2.1

Choose a tag to compare

@blackwell-systems blackwell-systems released this 23 Jun 18:00

Flatten Opt-Out

  • encode_generic(data, GenericOptions(no_flatten=True)) disables nested object flattening
  • Backward compatible: encode_generic(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)

Choose a tag to compare

@blackwell-systems blackwell-systems released this 23 Jun 04:31

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 1M random + 1M adversarial round-trips
  • 17-format mega-gauntlet: PERFECT data integrity
  • Falls back to attachment mechanism for non-flattenable cases
  • Round-trip guarantee preserved

Full Changelog: v2.1.1...v2.2.0

v2.1.1

Choose a tag to compare

@blackwell-systems blackwell-systems released this 18 Jun 17:53

Patch release. Fixes encoder quoting for edge cases involving bracket-colon patterns in string values. 10M fuzz iterations, zero failures.

Full Changelog: v2.1.0...v2.1.1

v2.1.0

Choose a tag to compare

@blackwell-systems blackwell-systems released this 14 Jun 21:52

Spec v3.1 Conformance

Spec change

  • tool field 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.0: Inline Schema Encoding

Choose a tag to compare

@blackwell-systems blackwell-systems released this 13 Jun 06:18

v2.0.0: Inline Schema Encoding

The generic profile encoder now produces inline schema format for nested objects with 3+ scalar fields. This is a breaking change from v1.x output.

Breaking Changes

  • encodeGeneric output format changed (inline schemas, no attachment indentation)
  • Decoders no longer accept 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
  • 25.5% fewer tokens than TOON across 15 real-world datasets

Integrity

  • 1B+ lossless round-trip iterations across 6 language implementations
  • 100% comprehension accuracy on every frontier model tested
  • 156 conformance fixtures passing

Full spec: https://github.com/blackwell-systems/gcf/releases/tag/v3.0.0

v1.0.1: CLI generic profile

Choose a tag to compare

@blackwell-systems blackwell-systems released this 10 Jun 19:30
  • CLI: encode-generic and decode-generic subcommands
  • python -m gcf entry point
  • Both graph and generic profiles supported from the command line

gcf-python v1.0.0

Choose a tag to compare

@blackwell-systems blackwell-systems released this 10 Jun 10:46

SPEC v2.0 implementation

126/133 conformance fixtures passing (7 skipped: session, delta, binary UTF-8, negative zero, graph encode). 40M property-based round-trips with zero failures.

Breaking changes from v0.5.0

  • encode_generic emits GCF profile=generic header
  • decode_generic requires GCF profile= header
  • Strings colliding with typed literals are quoted
  • Full JSON string escaping and number grammar
  • - for null, ~ for absent, ^ for nested attachments
  • ##! summary trailer replaces ## _summary
  • Graph encoder emits profile=graph

Install

pip install gcf-python==1.0.0