⬅ ️Back to main explainer
FactsPack v0.3 — Roadmap, adversarially reviewed

Fix the contract first.

FactsPack combines schema-once tabular streams with dictionary interning. This roadmap that delivered v0.3 / agent-v5 was adversarially reviewed three ways — by Claude, Codex, and Antigravity. The review found the v0.2 foundation has contract bugs the roadmap was about to build on. The honest path: repair the contract, prove the core claim with a real benchmark, then add features one measured delta at a time.

Update · June 2026 — v0.3 has since shipped.

This page is the dated review record that preceded the release. Since 2026-06-13: the Gate-0 contract repairs landed; byte-determinism is proven and shipped (canonical POSIX paths, content-addressed snapshot id); the agent-v5 wire (opt-in typed columns, corpus tag, ; caps/types/gschema) and the master/diff chain (~84% smaller diff in the measured case) are implemented and tested; and the P0.1 benchmark has been run — ~38% fewer tokens than records-JSON (up to 54% vs HTML) and 98.2% retrieval accuracy tied with JSON in a single-model pilot (Claude Sonnet 4.6, 8 repos), with the ≥3-model benchmark still pending. Read the "Unknown / pending" states below as the open questions at review time — now largely answered on the live page.

Three-way cross-verification · 2026-06-13

The plan is sound as a benchmark-gated plan — and dangerous as anything more.

An independent 145-agent red-team (46 objections, 30 survived three-skeptic refutation) and a separate contract review converged on the same load-bearing findings. The single best decision — making a public benchmark the gate, and shipping no unmeasured number as fact — is real. But the set scheduled a diff-chain economic moat on top of a v0.2 row-count rule that is internally self-contradictory for diffs, routed probabilistic symbol matching into a destructive delete/replace path, and asserted two legal/security claims as settled fact. None of that kills the roadmap; it puts a correctness gate in front of it.

What changed on this page: the impact calculator (which rendered unmeasured weights as precise percentages) is replaced with an honest evidence-state matrix; the quadrant no longer plots .pack at invented coordinates; fabricated impact figures, the "Bulletproof" label, and the "process boundary escapes AGPL" legal claim are struck.

Claude — roadmap + workflow red-team Codex — contract & state-safety Antigravity — adversarial contract review verified against codec bytes

Dependency order, not optimism

Every later stage depends on the one before it. Chain work — the unique economic moat — comes last, because it cannot be built on a contract that two conformant readers resolve differently.

Gate 0 · now

Repair v0.2 + freeze

Fix the contract bugs below. No new normative tables until the wire is self-consistent and byte-determinism is proven (not assumed).

Gate 1

Conformance

Byte-exact fixtures + positive/negative vectors a strict decoder enforces. Independent lossless round-trip oracle.

Gate 2 · P0.1

Measure the core claim

Private, statistical benchmark: does interning + legend beat JSON / Markdown-KV on a real code map? Publication is owner-gated.

Gate 3

Additive features

Admit Wave-1 items one at a time, each behind a measured delta that clears a pre-registered confidence interval.

Gate 4

Identity → chains

Prove stable, deterministic symbol identity, then build the master/diff chain on top of it.

Format Landscape — Cost vs. Accuracy

Only the three points below are measured: they come from a published third-party retrieval benchmark (GPT-4.1-nano, 1,000 synthetic records — not code maps). FactsPack's position is deliberately not plotted: where .pack lands is exactly the question P0.1 exists to answer, and inventing a coordinate would be the fabricated precision this review removed. The aim is the top-right quadrant; whether the legend gets it there is unproven.

Retrieval Accuracy (Comprehension)
CSV (44.3%)
CSV Format
Accuracy: 44.3%
Token Savings: High (~80%)

Lack of local keys and positional relationships causes attention heads to misalign nodes/edges, degrading graph retrieval.

JSON (52.3%)
JSON Format
Accuracy: 52.3%
Token Savings: None (0%)

Repeating keys provide explicit context, but the excessive repetition results in massive, costly token bloat.

Markdown-KV (60.7%)
Markdown Key-Value
Accuracy: 60.7%
Token Savings: Negative (-50%+)

Highly structured markdown layout is easy for models to comprehend but uses an unsustainable token budget.

.pack target — ? (P0.1)
Token Efficiency (Berry Savings)

Why dense positional formats can hurt accuracy

The published evidence puts CSV/pipe-delimited at the bottom of retrieval accuracy — columns with no repeating labels add an indirection layer. .pack shares that density (plus interning), which is the risk P0.1 must test, not a settled result. The cited graph-distance "6×" figure is from synthetic graph QA, not code maps.

The bet v0.3 is making

The in-band legend, explicit types, and incident edge ordering are hypothesised to cancel the density penalty while keeping interning's token savings. Plausible, evidence-informed — but unproven on a code map until measured. The honest claim is a hypothesis, not a coordinate.

The Optimal Path Timeline

We split the transition into four distinct stages: Strategic Foundations (P0) to secure credibility, Wave 1 compatible extensions, Wave 2 breaking upgrades, and Wave 3 ecosystem scaling.

G0
Gate 0 · blocking

Repair the v0.2 contract before any v0.3 feature

1. Valid canonical examples: the spec's own worked examples use spaces, not the mandated tab 0x09 (verified) — regenerate them from byte-exact fixtures with a visible <TAB> view.
2. Fix diff/master count semantics: a diff with header rowCount=0 contradicts the trailer's "rows == header count" rule. Define master / diff-sentinel / op-count as separate quantities; enforce equality for masters only.
3. Strict vs legacy decoder profiles: a missing trailer is silently accepted today — strict v0.2 must reject it. Add resource limits (the decoder parses untrusted repos on Workers).
4. Prove byte-determinism: the cache moat assumes "same input → same bytes," but float formatting, dict-key order, and Windows-vs-POSIX paths are unpinned and untested. Pin them; add a conformance test.
No new normative tables ship until these are fixed and determinism is proven — not assumed.
P0
Strategic

Foundations & Credibility

1. Private accuracy benchmark (the gate): measure .pack vs JSON / CSV / Markdown-KV / TOON across 3+ model families on a real code map, with pinned models, fixed temperature, and pre-registered confidence intervals — gate on the lower CI bound, not the mean. Publication is owner-approved only.
2. AGPL-3.0 codec policy (settled): retain AGPL-3.0 + commercial for all code including the codec. Ecosystem viability comes from first-party ports and a permissively-licensed spec/fixtures (owner's open sub-question) — not from claiming a process boundary escapes copyleft, which is a legal question for counsel.
Decision: AGPL-3.0 retained by the owner; adoption risk managed at the spec/fixtures layer, not via unverified legal claims.
W1
Wave 1

Additive & Compatible Extensions (v0.2.x)

1. Incident Edge Ordering: Group outgoing edges from a single source node together. Keeps connected nodes close in context.
2. Communities Table: hierarchical region labels (GraphRAG-style). Verified defensible on the real graph (4 communities cover 50%), but the summary column must be cut — non-deterministic LLM text breaks the hashed wire. Heuristic label needs an exact tie-break rule.
3. Datatypes in Legend (Compatible): column typings in ; comment lines (e.g. ; types symbols id=int) so legacy readers ignore them. Scope to storage-form specials the prose legend can't disambiguate; the borrowed "+20%" figure is dropped pending measurement.
4. In-band Legend & Metadata: Self-describing schema definitions, null cell markers, and escaping rules written directly into comment lines (; lines).
5. SHA-256 Integrity Verification: Final trailer validation (; end rows=... sha256=...) to prevent truncated payloads from misinforming agents.
6. Hot-Reference inline hints: Basename prefixes added to most-referenced identifiers (e.g. F12~cli.ts) to prevent lookup errors.
7. Unified Intern Namespaces: Paths and symbol columns share a unified identifier space across tables, removing key collisions.
Impact unmeasured. Each item must show a measured delta on the P0.1 code-map benchmark or it does not ship — "emit what's computed" is a hypothesis, not a result.
W2
Wave 2

Breaking Core Changes (agent-v5)

1. SCIP Position-Free Monikers (Strict + Lite): replace line-number IDs with stable descriptors. Lite (heuristic) monikers are hints only — they may never key a delete/replace, because a probabilistic match can silently mutate the wrong row. On uncertainty: delete-plus-add or re-index.
2. Master/Diff Chains: sequenced chains with manifest pinning, built only after identity is stable. Coalescing thresholds are emitter policy, not wire, and stay unmeasured — the rebuild trigger is set by the benchmark's chain-depth curve, not a guessed file count. Needs a concurrency story for multi-agent repos.
Cache economics are the real moat — but unproven: Anthropic's cache has a ~1024-token floor and ~5-min TTL, so the win can be negative for small or intermittent packs. P0.1 must price it with real billing numbers.
W3
Wave 3

Ecosystem Scaling & Hardening

1. Python Port & pip/npm CLI: Port parser to Python where modern agent frameworks live.
2. Conformance Vectors: Spec split with test fixtures to ensure multi-language parity.
3. Delimiter escape armor (shipped) — XML is organization, not security: strict \t \n \\ escaping is real defense. Wrapping a pack in XML tags is a prompt-structuring tip, not injection armor — a cell containing </tag> can close it. The real defenses are tool-side decode, instruction-taint tracking, and model alignment.
4. Authenticity (out-of-band): a detached signature over the whole artifact, verified in the loader before bytes reach the model. It attests origin only, never content safety — the reading LLM cannot verify it. Needs a key/trust/rotation model first.
Goal: frictionless third-party reading + agent-framework adoption — in tension with AGPL, and dependent on the contract and benchmark gates clearing first.

Cross-Agent Coordination & Coexistence Protocol

Three advanced coding agents—Claude Code, OpenAI Codex, and Antigravity—cooperatively define the FactsPack v0.3 / agent-v5 standard. We respect each agent's native constraints, reasoning styles, and execution frameworks to deliver a unified, high-performance transport standard.

Claude Code

  • Prompt-Cache Optimization: benefits from cache discounts when a pinned master prefix stays stable — subject to the cache's minimum-prefix floor and TTL, which P0.1 must measure before the discount is claimed as a number.
  • XML for structure, not shielding: wraps long-context data in tags as a recall/organization aid. This is not an injection boundary; safety comes from tool-side decode and treating every cell as untrusted data.
  • Process Separation (architecture only): integrates with the codec over MCP/stdio boundaries. Whether that boundary changes AGPL obligations is a question for counsel, not an engineering guarantee.

OpenAI Codex

  • GraphRAG Traversal: Integrates Incident Edge Grouping and precomputed paths tables to bypass multi-hop traversal reasoning decay.
  • Dual-Mode Compilation: Employs Lite AST/Regex parsing mode alongside Strict SCIP parsing to bootstrap symbol indexing without heavy compiler chains.
  • Neo4j Exporter: Relies on quick translation mapping to Neo4j/Cypher backends for graph-database-guided code search.

Antigravity

  • Adversarial Hardening: isolates metadata typings in comment legends to preserve legacy-reader compatibility; found the tokenizer column-shift attack on empty cells.
  • Contract-first sequencing: coalescing thresholds are emitter policy, not settled constants — the rebuild trigger waits on a measured chain-depth curve, not a guessed file count.
  • Empirical Validation: spearheads the retrieval-accuracy benchmark (private first; published only on owner approval) to verify legend efficacy across 3+ LLM families.

Normative Coexistence Protocols

Escaping (real) vs. XML (structure)
Text columns carrying source snippets or linter messages MUST be strictly escaped (\t, \n, \\) — this is the load-bearing defense against column-splitting and grammar injection. XML wrapping is offered as an optional prompt-organization aid; it is explicitly not an injection boundary (a cell can contain a closing tag), and must never be labelled "shielded" or "bulletproof." Defense in depth is tool-side decode + instruction-taint tracking + treating every cell as data.
Strict vs. Lite Monikers
v0.3 defines a dual symbol-moniker system: Strict Mode uses Sourcegraph SCIP schemas (CI/CD); Lite Mode uses regex/AST heuristics for build-free editors. Both may populate the same moniker field, but Lite monikers are non-authoritative hints — they may not key a +/x delta operation, and a chain must not mix modes unless both provably emit byte-identical keys. A probabilistic match is not a primary key.
AGPL-3.0 boundary (architecture, not legal advice)
The codec stays AGPL-3.0 + commercial (owner's settled decision). Integrations are architected to talk to the codec over stdio/MCP process channels. Whether that boundary affects copyleft obligations is a fact-specific legal question deferred to qualified counsel — this page makes no claim that a process boundary "escapes" the AGPL. Ecosystem viability is pursued through first-party ports and (owner's open call) permissively-licensed spec text + conformance fixtures.

Adversarial Review & Hardening Report

Three independent reviews converged on the same risks. Below are the mitigations for the design-level risks; the source-verified findings that follow are confirmed against the actual codec and spec bytes — those are bugs, not hypotheses.

1. Legend Type Pollution

Risk: Embedding datatypes directly in the & schema line (e.g. id:int) crashes or misleads legacy v0.2 readers.

Mitigation: In Wave 1, datatypes MUST be declared in standard comment lines (e.g. ; types symbols id=int) which legacy readers ignore. Defer inline type tokens to Wave 2.

2. Custom Table Heap Blowup

Risk: Naive legacy parsers may crash or run out of memory when encountering new tables like communities.

Mitigation: Emitters must append new tables after core v0.2 tables. Test suites must validate that legacy parsers silently disregard unknown trailing tables without allocating heap memory.

3. SCIP Compiler Dependency

Risk: Requiring heavy compiler-level indexers for SCIP monikers blocks lightweight agent and IDE plugin integrations.

Mitigation: Define a Dual-Mode Symbol Indexing Spec: use Strict SCIP in CI/CD, but provide a heuristic AST/Regex-based Lite Fallback for build-free local environments.

4. Diff Chain Bloat & Attention Decay

Risk: Long sequences of incremental diff packs (e.g. 20 edits) bloat the token footprint and cause attention lookup decay.

Mitigation: Enforce a Coalescing Threshold. If a diff chain exceeds 5 files or 20% of the master pack's size, rebuild a new unified master pack immediately.

5. Token Injection Payload Shielding

Risk: Attacker code carrying delimiters can delete data. XML wrappers are for prompt structure, not security boundaries: cell contents containing </> can close tags prematurely.

Mitigation: Escaping of delimiters (\n, \t, \\) in text cells. Offer XML tags for prompt organization, but enforce tool-side decoding, instruction taint tracking, and model-level alignment.

6. Cache Invalidation Sync Race

Risk: Minor file edits out of order can trigger diff rebuilds that invalidate the LLM's prompt prefix cache; mid-session diff insertion before the conversation busts the very prefix it aims to preserve.

Mitigation: Pin master+chain once at session start (immutable prefix); deliver later updates as chronological messages appended after the conversation. A latest.manifest orders diff hashes — this improves cache stability but cannot guarantee hits (floor/TTL apply).

7. Row-Count Semantic Contradiction

Risk: Incremental diffs with header rowCount=0 conflict with the trailer's requirement to match decoded records.

Mitigation: In v0.3, define separate quantities: header rows (materialized baseline count), header ops (patch operations count), and trailer records (physical transmission lines).

8. Lossy Converter Edge Cases

Risk: Converter is labeled lossless, but Unicode minus collisions, nested JSON objects, and colliding column names collapse data structures.

Mitigation: Output warnings for lossy conversions and explicitly warn developers that tabular flattening is lossy for complex nested JSON structures.

9. Optional v0.2 Integrity Bypass

Risk: Reference decoder allows v0.2 packs to drop the trailer, falling back to unverified v0.1 parsing, permitting truncation attacks.

Mitigation: Enforce strict validation, rejecting v0.2 packs that omit the `; end` trailer unless compatibility is explicitly configured.

Source-verified findings

These were checked against the actual codec and spec bytes by two independent reviews — they are confirmed defects, not design opinions. The first four block Gate 0.

Criticalverified · triple-confirmed

Canonical examples aren't valid wire bytes

FACTSPACK.md:81 mandates tab 0x09, but the worked examples at :241 and :272 contain zero tabs (all spaces). The decoder splits strictly on \t — copy the spec's own "lossless" example and it is rejected.

Fix Generate docs from byte-exact fixtures; show a visible <TAB> companion; decode-and-reencode every normative example in CI.

Criticalverified · bundle.mjs:112/114/431

Diff row-count contract is self-contradictory

A diff has header rowCount=0 ("patch only") but the spec demands trailer rows == header count when not -. 0 ≠ -, so the rule requires 2 == 0. The shipped decoder silently never enforces it — so the "cite or refuse" integrity contract is a no-op for the exact file the chain emits per commit.

Fix Separate named quantities: master header = baseline count; diff header = 0 sentinel bound to kind=diff; trailer = physical op count; equality required for masters only. Block the chain until fixed.

Criticalverified · decoder

Strict v0.2 integrity is optional

A trailer-less pack returns success; the decoder cannot tell a legitimate v0.1 pack from a truncated v0.2 one, and never validates header.rowCount. The spec says v0.2 consumers MUST verify the trailer is present — the decoder doesn't.

Fix Explicit strictV02 vs legacy profiles; strict requires trailer + header + kind-legality + duplicate rejection + resource limits.

Highverified · validate.mjs:21

The validator proves acceptance, not losslessness

The test oracle maps literal - (U+2212) and counts the lossyDash cases as pass under a lossless label. It normalizes away the exact loss it should catch. "15/15 pass" is smoke coverage, not a round-trip proof.

Fix Independent exact round-trip oracle; reject ambiguous input with a precise error rather than normalizing it green.

Highblind spot · uncaught by prior reviews

Byte-determinism is assumed, not proven

The cache moat rests on "same input → same bytes," but float formatting (imp=0.0242 — digits? rounding?), dict-key order, free-form legend wording, and Windows-vs-POSIX path separators (this repo is win32) are unpinned with zero conformance test. If any varies, the moat is already broken.

Fix Make canonicalization normative incl. number formatting and path normalization; add a cross-platform determinism conformance test before selling the cache story.

Highblind spot · live deployment

Decoder has no resource limits — a live DoS hole

The current branch parses .pack from untrusted GitHub repos on Workers. A pathological pack (billions of forward @ refs) exhausts memory before the sha256 trailer is reached — whole-file dictionary resolution is post-parse. The adversarial corpus lists poisoning but not resource exhaustion.

Fix Configurable caps on bytes, lines, rows, columns, tables, dictionary entries; add resource-exhaustion cases to the corpus.

Evidence-state matrix

This replaces the old impact calculator, which rendered unmeasured feature weights as precise percentages — the exact fabricated precision this review removed. Every claim below carries an honest evidence state. No score is invented; an unknown stays unknown until P0.1 measures it.

Measured — observed in tests/real packs Hypothesis — plausible, not benchmark-derived Unknown — P0.1 must measure Rejected — claim struck
Claim / featureEvidenceVerdictNote
Fewer tokens than JSONinterning + schema-once Measured Keep The one genuinely measured property — real packs decode smaller than equivalent JSON. The specific "81%" was a sample, not a universal figure.
SHA-256 trailer integritytruncation / tamper detection Measured Keep Tests confirm truncated and tampered packs are rejected — when a trailer is present. Making it mandatory for v0.2 is a Gate-0 fix.
Delimiter escaping stops column-split injection\t \n \\ Measured Keep Shipped and real. This — not XML wrapping — is the load-bearing injection defense at the grammar level.
Retrieval accuracy vs JSON / Markdown-KVthe core claim Unknown Gate 2 Never measured on a code map. The borrowed 44–61% figures are from a synthetic-record task on a different model. This is the question P0.1 exists to answer.
In-band legend cancels the density penaltythe central bet Hypothesis Gate 2 Evidence-informed (explicit metadata helped on other tabular tasks) but the legend is already spent; whether it nets positive on .pack is unproven.
Incident edge ordering helps traversal53.8% vs 19.8% (borrowed) Hypothesis Rework The number is from synthetic graph-QA with bare-integer nodes — not .pack, which already groups edges by source. Codify the ordering as a canonicalization rule; drop the accuracy claim.
Communities table aids reasoningGraphRAG-style Hypothesis Rework Structure verified defensible (4 communities cover 50% of the real graph). But the non-deterministic summary column must be cut from the hashed wire, and the heuristic label needs an exact tie-break.
Explicit datatypes raise accuracy"+20%" (borrowed) Hypothesis Rework Single-model generic-tabular figure, double-counted against the already-mandatory legend. Scope ; types to storage-form specials; gate the rest on a measured delta.
SCIP monikers shrink diffsstable symbol identity Hypothesis Gate 4 Sound by construction (stable ids churn less), but the actual benefit is unmeasured because the chain it serves does not exist yet.
Prompt-cache economics (the moat)"99% cache hits" Unknown Gate 4 Real moat in principle, but the ~1024-token cache floor and ~5-min TTL are unpriced — the win can be negative for small or intermittent packs. Needs real billing numbers, not a "99%".
Chain coalescing thresholds"≤5 diffs / 20%" Unknown Rework Both 5 and 8 are guesses; file-count is a weak proxy. Emitter policy, not wire — set by the benchmark's chain-depth curve.
Byte-determinism ("same input → same bytes")foundation of the moat Unknown At risk Assumed, never tested. Float formatting, dict-key order, and Windows-vs-POSIX paths are unpinned with zero conformance test. Prove it before selling the cache moat.
Lite monikers as chain identityheuristic matching Rejected Hints only A probabilistic match cannot key a delete/replace — one false match silently mutates the wrong row. Demote to non-authoritative hints; uncertainty → delete-plus-add.
XML wrapping = injection "shield""Bulletproof" / "shielded" Rejected Strike Security theater — a cell can contain a closing tag. XML is a prompt-organization aid only. Real defense: tool-side decode + instruction-taint + treat every cell as data.
Process boundary "escapes" AGPLintegration mitigation Rejected Strike An unsettled legal conclusion stated as engineering fact. State the architecture only; defer the copyleft question to qualified counsel.
Why a matrix, not a calculator: a slider that adds "+15% for incident ordering, +12% for communities" and caps at 92% manufactures precision the project has not earned. Per the R5 claims policy, no unmeasured number ships as fact on a public surface. When P0.1 produces measured deltas with confidence intervals, the Unknown and Hypothesis rows here become Measured — with ranges, not single digits.