GAP / gxai.dev

GAP GX AI Protocol — wire version gap/0.1

A wire protocol for delivering corporate ESG data as raw activity data, signed at source, straight to an investor's AI agent over MCP and REST — with no PDF disclosure report in between.

GAP does not carry emissions. It carries activity data, and the evidence that it is genuine.
  • Status: Draft
  • wire gap/0.1
  • Ed25519 + SHA-256
  • Reference implementation
  • License: undetermined

This English site is an informative translation. The Japanese specification is normative — where the two disagree, the Japanese text governs.

What changes

Every human hop strips the evidence away

In conventional disclosure, a figure passes through aggregation, presentation and re-keying before it reaches an investor. What survives is a number — with no way for the recipient to check which measurement it came from.

Conventional

Core systems
Staff / consultants
(aggregation, embellishment)
PDF report
Analyst
(re-keying)
Assessment

GAP

Core systems / sensors
[signature]
GAP Node
[MCP / REST]
Investor AI agent
(computation and verification on the receiving side)

Emissions are activity data times an emission factor, and choosing the factor is a judgement that varies by regime, standard and year. Letting the reporting company settle that judgement first is where embellishment begins. GAP separates factor selection out as an explicit choice made by the recipient, and asks the company for nothing but what it measured.

What has been measured

This is not a gap better parsing will close

By the stated purpose in the introduction to ISO 32000-2:2020, PDF exists for "preservation of document fidelity independent of the device, platform and software", and its production stage is characterised as "the final-state form for distribution to end users" [S4]. It keeps position precisely; what that position means is not something the format carries by default. What happens downstream has already been measured.

What was measuredResultSource
Table detection F1 across 400 financial documents (annual reports, SEC filings) 0.06 pdfplumber · 0.10 Camelot · 0.24 Tabula · 0.79 TATR
In the same comparison, body-text extraction reaches 0.95–0.99
Adhikari & Agarwal (2024)
Relating a KPI to its value across 81 hand-annotated real 10-K filings Best model reaches Relation F1 22.68% Deußer et al., ICMLA 2022 (KPI-EDGAR)
Extraction from the 2022 ESG reports of 166 HKEX-listed companies Best configuration (GPT-4 + RAG) is 76.9% accurate Deng et al. (2023), ESGReveal
Time to transcribe one figure (practitioner's own account) HTML ~20 min · PDF ~30 min · image ~50 min. From XBRL, 1–2 sec XBRL US ESG Working Group
Table candidates in one 462-page sustainability report Raw parser verdict 460 pages → mechanically filtered on task-specific conditions, 62 pages Authors' own JASAG v3.1 record
unpublished; not exhaustively checked by hand

The shape of the failure is what matters. On the same corpus, body text comes out at 0.95–0.99 while tables collapse to 0.06–0.24 [S17]. The extractors are not simply bad at their job — nothing in the format says that a number is part of a table. So GAP does not try to parse PDFs better. It puts the signature one layer earlier, before anything is flattened into a document.

Full citations and the extent to which each was checked are in evidence-sources.json. They are drawn from the evidence ledger of chapter 7 ("What PDF disclosure loses: provenance, coordinates, computation") of a book in progress, Non-Financial Information Without Evidence. That book is unpublished.

The three gaps in the name

Three separate disconnects to close

Disclosure GAPReported figures drift from field data

Only activity data signed with the source's private key circulates, so any alteration in transit is mathematically detectable.

Time GAPAnnual reporting vs. real-time decisions

Continuous ingest into an append-only stream (continuous auditing). Any window can be computed on demand.

Agent GAPProse documents vs. deterministic interfaces

Computation and verification are exposed as MCP tools. The same arguments always yield the same figure and the same hash.

Zero-Embellishment Constraint

A payload carrying derived emissions must be refused

GAP carries activity data only. A payload whose metric — or any key under meta — contains a term denoting derived emissions (co2, co2e, ghg, emission, scope1|2|3, tco2, carbon_footprint) must not be accepted by a node.

Accepted — only what was measured
{
  "spec": "gap/0.1",
  "source_id": "jp-demo-plant-chiba-meter-01",
  "seq": 1,
  "metric": "electricity_kwh",
  "period_start": "2026-07-01T00:00:00Z",
  "period_end": "2026-07-01T01:00:00Z",
  "value": 812.4,
  "unit": "kWh",
  "quality": "measured",
  "prev_hash": null,
  "meta": { "line": "A", "tariff": "peak" }
}

A measurement in kWh. What it gets multiplied by, and what the result is called, is the recipient's decision.

Refused — embellishment_rejected
{
  "spec": "gap/0.1",
  "source_id": "jp-demo-plant-chiba-meter-01",
  "seq": 1,
  "metric": "scope2_co2e_t",
  "period_start": "2026-07-01T00:00:00Z",
  "period_end": "2026-07-01T01:00:00Z",
  "value": 0.351,
  "unit": "tCO2e",
  "quality": "measured",
  "prev_hash": null,
  "meta": { "line": "A", "tariff": "peak" }
}

The factor has already been chosen. Whose judgement produced this number has been erased.

For the same reason, no unit conversion, rounding or correction may happen in transit. The value the instrument produced is the value that travels. Using estimated or corrected readings is legitimate in itself, but the moment they are mixed in without a quality label, an unembellished stream becomes indistinguishable from an embellished one.

Layers

Meaning, query, proof

1. SemanticStandardising meaning

One reading's payload is the byte string that gets signed. Timestamps take exactly one form, YYYY-MM-DDTHH:MM:SSZ — variation would make the signed bytes irreproducible.

seq increments from 1 per source, so a gap in the sequence remains as evidence of a deletion or a missed reading.

2. Query & executionMCP native

Six read-only, idempotent tools. Responses are capped (1000 points by default); beyond that the node returns too_many_points rather than silently truncating.

compute_emissions refuses to return a figure when the factor is not uniquely determined, returning factor_ambiguous with the candidates instead.

3. TrustProof and permission

Canonicalization is an RFC 8785 subset (sorted keys, no whitespace); the hash is SHA-256; the signature is Ed25519; the chain is prev_hash plus a monotonic seq per source.

A node must not trust the verification flag recorded at ingest — it re-checks immediately before computing.

MCP tools

Six tools are all an investor agent sees

All read-only and idempotent. The same logic is also exposed over REST at /api/v1/gap/*.

ToolRole
list_sourcesDiscover primary data sources, including the granularity the calling key may see
get_activity_dataRaw activity data, up to the permitted granularity, with provenance hashes
list_emission_factorsApplicable factors, each with a citation URL and publication date
compute_emissionsActivity data times an explicitly specified factor, computed deterministically
verify_provenanceRecomputes signatures and the hash chain (returns no values)
detect_anomaliesStatistical detection of gaps, missing seq, outliers and flatlines

Verifiability

Implementations can self-check against published vectors

Fixed vectors for canonicalization, hashing, chaining and signing are distributed with the spec. The signing key is the published RFC 8032 §7.1 TEST 1 key — deliberately a value no real source can use.

Canonical JSON (the exact byte string that gets signed)

{"metric":"electricity_kwh","period_end":"2026-07-01T01:00:00Z","period_start":"2026-07-01T00:00:00Z","prev_hash":null,"quality":"measured","seq":1,"source_id":"jp-demo-plant-chiba-meter-01","spec":"gap/0.1","unit":"kWh","value":812.4}

payload_hash = SHA-256(canonical_json)

5f42e6df31af80d66e1ee0b906ab172bd9b7cb41c34864d853ee57c3b84a5484

Self-check in the reference implementation

node scripts/health/gap-selftest.mjs   # canonicalization, hashing and signature vectors
node scripts/gap/e2e-local.mjs         # sign -> ingest -> compute -> verify -> MCP, end to end

Vectors: test-vectors.json

Granular access control

Confidentiality is not a choice between hiding and showing everything

A factory's real-time electricity draw can reveal utilisation and unit cost. GAP settles this by coarsening the time granularity while keeping the disclosure verifiable (bucket_hash).

disclosure_levelWho may read itGranularity
publicEvery approved API keyCoarsened to min_bucket_seconds (e.g. hourly metering disclosed daily)
engagementOnly keys holding raw_access_grantsA grant may permit finer granularity
restrictedNode internal only

An engagement source is still visible as existing to keys without a grant (access.granularity = "none") — hiding it would remove the entry point for engagement.

Where it bites

What GAP closes, and what it does not

The phenomena collapsed into the single word "greenwashing" separate into at least eight kinds [B1]. GAP reaches three of them, and in every case only along one path: a record already committed to the chain being quietly rewritten afterwards. Two more are partial, and the remaining three lie outside what any wire protocol can reach [B2].

KindWhat happensEffect of GAP v0.1
Loss of information Source records, computation and correction history disappear on the way into a PDF reaches it, narrowly Signed at source, with provenance kept by the append-only chain of payload_hash and prev_hash. What this detects is a broken link where a committed record was later rewritten — not evidence that was never committed, nor a chain that simply stops
Numerical embellishment Computing emissions, reduction rates or renewable share inappropriately reaches it, narrowly The Zero-Embellishment Constraint, plus returning no figure when the factor is ambiguous, closes at least that one path. Putting a false value into a permitted field (say electricity_kwh) and calling it measured is not prevented by this constraint alone
Methodological embellishment Changing base year, emission factor or estimation method to look improved reaches it, narrowly Rewriting past values tends to surface as a broken link. But adding the change as a legitimate new record contradicts nothing in the chain rules, and GAP has no provision for judging whether the change was methodologically sound
Boundary embellishment Dropping inconvenient subsidiaries, regions or Scope 3 categories partial list_sources returns registered sources only, so an entity never registered does not appear in that query either. Nothing enforces completeness of the reporting boundary; closing that requires reconciliation against an external legal-entity identifier system such as LEI. Scope 3 chaining is also undefined in v0.1
Selective disclosure Publishing only the indicators that improved partial An engagement source is visible as existing even without a grant. But nothing enforces continuity — which indicators must be published, and how often
Falsehood Describing measures that were never taken structurally out of reach Arises when the holder of the signing key signs false activity data, or when the instrument itself is rigged. GAP places this explicitly outside its design scope
Temporal embellishment Presenting future targets as if they were current performance structurally out of reach A matter of how the accompanying prose is written. GAP governs the path data travels
Narrative embellishment Covering reality with an unevidenced value-creation story structurally out of reach As above. No wire protocol can govern honesty

A signature does not attest that a value reflects reality. It attests only that a value signed with a registered key was not altered afterwards. Whether the instrument is correctly installed and calibrated lies outside GAP and remains the work of assurance and audit. Not having been tampered with, and having been measured correctly, are different questions.

Which leads to the most uncomfortable possibility for this protocol itself. Where the institutions for correcting a wrong figure remain thin, a figure that is wrong but demonstrably untampered can end up being trusted more, precisely because it is untampered [B3]. Above the layer that detects tampering, a separate layer is still needed: what happens when the value itself turns out to be wrong. (A concern drawn from the evidence, not a measured result.)

The eight kinds come from the framework of a book in progress [B1]. The mapping onto GAP follows the analysis derived in that book's chapter 8 from the specification text alone [B2]. The book is unpublished.

Deliberately out of scope in v0.1

What this version does not do

These remain open as v0.2 questions. They are listed so that no one reads a capability into the spec that is not there.

  • Zero-knowledge proofs / differential privacy — confidentiality currently goes as far as coarsening time granularity, and no further toward proving validity without revealing the raw data
  • Key rotation procedurepublic_key_hash is recorded on each reading so past data can be re-verified, but the rotation protocol itself is undefined
  • Cross-verification between nodesinput_hash lets identical inputs be matched to identical results, but there is no inter-node audit protocol
  • Scope 3 / supply-chain chaining — referencing activity data held by another company's node is undefined; v0.1 is closed over the sources within one node
  • Streaming subscriptions — polling only; webhook and SSE push are undefined
  • Regime mapping (CSRD / SSBJ / GHG Protocol) — GAP only separates activity data from factors; mapping to a particular regime's line items is the recipient's responsibility

Status

Where this stands

SpecificationDraft (wire version gap/0.1)
LicenseUndetermined
Reference implementationPrivate repository kokubee/gxceed (not publicly accessible at this time)
Provenance of this distributiongxceed@19f2540 / tree a77935e

This is a worked example, not a solution [B4]. It was written to show what closes and what remains when parts that already work in adjacent domains are assembled in a non-financial reporting context. It has no track record as an industry standard and has not been independently verified. Financial disclosure already has a working precedent — XBRL US operates an official MCP server over SEC filing data — and that gap is itself the measure of what non-financial reporting has yet to catch up on.

Because the license is undetermined, this specification does not currently grant or guarantee the right to implement it. Please confirm before adopting it.

In the reference implementation, GAP_MCP_ENABLED and GAP_INGEST_ENABLED both default to false (fail-closed), and any distributed emission factor whose factor_id begins with demo- is a proof-of-concept placeholder that must be replaced with a published value before production use.

Why standardise

Only four things are fixed

If every company implements its own MCP server, the investor side's integration cost grows in proportion to the number of companies. GAP fixes only the following, and leaves everything else to each implementer.

  1. The byte string that gets signed (the canonicalization rules)
  2. How the chain is formed (prev_hash + seq)
  3. The names and input/output semantics of the tools (six tools)
  4. The constraint that activity data, not emissions, is what leaves the company

With those four in place, a single agent implementation on the investor side can connect to, verify and compare across any company's GAP node using the same code.