Repository navigation
Description
Summary
Research + design for forking a Rust KDL stack for ID, extending #5688
(KDL → JSON → atomic triples → SQL/PGQ). This issue runs Drew's KDL
thread to ground in three directions:
- Archaeology (laptop hunt): the missing KDL material Drew
remembered exists — it ispkgs/mappy/migrations/limit.kdl, his
Dec-2023 scratchpad, and it is the concrete ancestor of id: design: KDL as human presentation format + triples + ANSI graph SQL (SQL/PGQ) for ID data #5688's
triples design. - Archaeology (upstream): Drew's actual capability asks to the KDL
project were found — two GitHub Discussions inkdl-org/kdl
(CI: goreleaser workflow fails in setup on the next tag push — go-version-file points at go.work, deleted in Feb 2024 #344 Children Annotation, mcpx tests: assert the spawn happened in TestEnsureDaemonCancelledWhileWaiting #362 Property Annotation, both
Dec-2023) that were not adopted into KDL 2.0. Together with his
spec-era comments and his Go-ecosystem work (kdl-go, koanf), they
define the fork's extension list. - Fork base: fork
kdl-org/kdl-rs(thekdlcrate, v6.7.1) —
the only maintained, format-preserving, dual-version (1.0 + 2.0)
Rust KDL document parser, with serde and KQL built in. The
annotation generalization Drew wants is a contained AST change
there, and a rebuild-everything proposition anywhere else.
Umbrella: epic #2056. Parent design: #5688 (this issue supplies its
parser/implementation substrate and its annotation model).
1. Laptop hunt — what was searched, what was found
Searched (2026-11-04, laptop online): every *.kdl file under the
laptop home (deduped across the many worktrees/clones), plus content
greps for "kdl" over the laptop's zettel corpus (~/git/zettel),
cairn (~/git/cairn), hatch-personal, and notes trees
(~/hatch/notes, ~/git/fleet/notes, ~/queue-notes).
Not covered / honest gaps: the dozens of repo worktrees are clones
of the same trees (deduplicated, not re-read); the Atlas local chunk
store was not mined for documents; no ChatGPT conversations.json
export exists on the laptop (the late-2023 prose brainstorming remains
unrecovered — the #5688 follow-on stands).
1.1 The find: pkgs/mappy/migrations/limit.kdl (106 lines, Drew, 2023-12-17)
A design scratchpad inside the mappy graph/triples experiment
(Python + SQL migrations; cf. node.sql, crdb.sql beside it).
Committed 2023-12-17 — the same day as upstream discussion #362
below. Its key positions, verbatim in spirit:
-
Triples modeled as annotations — the direct ancestor of id: design: KDL as human presentation format + triples + ANSI graph SQL (SQL/PGQ) for ID data #5688 §2:
(subject)character "Brian" { (predicate)"writesBooks" (object)"Wish It, Want It, Do It" (object)"Faster Than the Speed of Love" (predicate)"travelsWith" (object)"Stewie" (object)"Peter" }
-
Parameterized / structured annotation payloads — far beyond the
spec's single bare identifier:(predicate#NotVeryWell)"writesBooks" (object#book#author:BrianGriffin)"Wish It, Want It, Do It" (object::Baby:Lois'sBaby::Kind-Of-Annoying)"Stewie" (object:FamilyGuy)"Peter" (yes:yes:no:::bool)"=" "yes" "no" "yes" (document:object)rdf { ... }
-
Annotations on every part — node names, argument values (and, in
the commented-out variant,(subject)character="Brian"prop-style
modeling), plus experiments that leave the grammar entirely
(`=(predicate),:=(object)"examples", annotations embedded in
comments/*(result)*/). -
The triples store sketched in comments, Dec-2023:
// nodes: id, type, key, value // links: id, type, from, to // meta_links: id, type, from, to -
An RDF / Dublin-Core record re-expressed in KDL under
(document:object)rdf, and a tail of deliberate lexical torture
tests (quote/escape/emoji edge cases) — parser-robustness probing.
This file is why the fork's annotation design (§4b) treats the
annotation slot as structured data, not a bare tag.
1.2 Other real KDL material on the laptop (all in developing-today/code)
| File | What it is |
|---|---|
pkgs/roc/out-in.kdl (39 ln) |
Roc syntax brainstorm in KDL form (known fragment; links kdl-play) |
pkgs/roc/platform.kdl (14 ln) |
Prose platform notes as KDL strings |
pkgs/identity/config.kdl + pkgs/identity/configuration/embed/config.kdl |
Production identity-service config written in KDL |
~/.config/zellij/config.kdl |
Tool config (zellij) — not Drew's design material |
1.3 Negative results
- No KDL documents or design notes in the laptop zettel / cairn /
notes corpora (oneflake.locksubstring hit only). developing-today/hygge(GitHub, 2022) is Drew's builder-only Rust
KDL crate ("knuffel or kdl-rs for deserialization :-)"); its
SPEC.mdis a vendored copy of the KDL 1.0 grammar. It is prior art
for the serializer half of our stack, not a parser base.
2. Drew's KDL-ecosystem threads — the capability-ask catalogue
Method: GitHub search (author: / commenter: / involves:) across
the kdl-org org and globally for "kdl", plus a full pass over
kdl-org/kdl Discussions via GraphQL (search does not index
Discussions — that is where the headline asks were hiding). All
threads below verified by reading them.
2.1 The two declined capability asks (define the fork)
| Thread | Date | Ask | Maintainer response | Outcome |
|---|---|---|---|---|
| kdl-org/kdl discussion #344 — Children Annotation | 2023-11-29 | "Allow annotating the children block in the same way that values and identifiers can be annotated." | tabatkins (spec editor): unconvinced — a node has only one child list, so the information "can just be expressed with a property or attribute"; asked for a use case. | Not adopted. KDL 2.0 grammar has no children annotation. |
| kdl-org/kdl discussion #362 — Property Annotation | 2023-12-17 | "Allow annotating properties in the same way that values and identifiers can be annotated." Drew supplied precedents: Go's lunjon/gokdl already implements Prop.TypeAnnot ((author)name="Jonathan"); Elixir's Kuddle supports it too (with annotations: [] — a list). |
tabatkins: parseable, but questions the value — keys are unique per node, so "all necessary context is already baked into their name"; asked for a use case. | Not adopted. KDL 2.0 grammar: prop := string '=' value — no key annotation. |
The irony the design should record: the use cases the maintainers
asked for existed the same week in limit.kdl (§1.1) — repeated names
disambiguated by role ((subject) / (predicate) / (object),
parameterized (object#book#author:BrianGriffin)) — exactly the
"same name, different role" rationale the spec itself accepts for
node annotations, extended to every part.
2.2 Spec-era participation (KDL 2.0 design batch, Nov-2023)
| Thread | Drew's position | Outcome in KDL 2.0 |
|---|---|---|
kdl-org/kdl #343 — prefix keywords with # |
Came around to supporting; asked whether # would be banned from identifiers / first-char, noting quoted names as the escape. |
Adopted: 2.0 keywords are #true / #false / #null. |
| kdl-org/kdl #342 — multiline comments in more places | "i think this should be legal, i don't know what it should do." | Partially adopted: 2.0 relaxed comment placement (e.g. // immediately followed by newline; comments in more positions). |
| kdl-org/kdljs #21 — KDL 2.0 compliance | 2024-12-29: nudged for a 2.0 update post-release (playground dependency). | Closed. |
2.3 Implementation-era threads (Go ecosystem, Dec-2023 → Apr-2024)
Drew was simultaneously building on KDL — a KDL config provider for
koanf, via kdl-go — and pressing the permissiveness philosophy the
fork inherits:
| Thread | Ask / work | Outcome |
|---|---|---|
| sblinch/kdl-go #3 (authored) | Marshal panic on lists in map[string]any; discovered the key=val prop-coercion; asked "is there a toggle somewhere?" and for an error instead of a panic. |
Fixed upstream (kdl-go list-marshal fix; Drew pulled it via koanf #267). |
| sblinch/kdl-go #4 (authored) | Data-model fidelity cluster: empty nodes unmarshal as nil vs empty map; duplicate node names with changing types should be last-wins, not an error; { "" 5 ; "" 6 ; } children mishandled; quoted "1" / empty-string identifiers vs bare-identifier rules; asked for behavior flags/toggles "to extend what is permissible past spec." |
Maintainer asked for isolated test cases; thread closed with "Fixed in 3d5e45f" (2024-04-09). Partially addressed. |
| knadh/koanf #265 / #266 (authored) + developing-today-forks/koanf PR #1, PR #3 | Contributed a KDL parser provider for koanf (Go config library); negotiated the emptyIsNil difference generically rather than special-casing KDL in tests. |
PRs merged in his fork; koanf gained its KDL parser from this work. |
| knadh/koanf #267 (authored) | kdl-go dependency update carrying the #3 fix. | Closed. |
| typestreamio/typestream #77 | Commented (local-data joins for stream filtering; libsql-as-file/URL). Tangential to KDL design. | Open; listed for completeness. |
Coverage caveat: issue/PR search + both ends of the Discussions list
were covered; comments Drew may have left inside other people's
discussions were not exhaustively enumerated.
2.4 The spec baseline (verified against both grammars)
Type annotations in KDL 1.0 (SPEC_v1: "a prefix to any Node Name
or Value"; prop := identifier '=' value; type := '(' identifier ')')
and KDL 2.0 (IETF-draft grammar: value := type? …,
prop := string '=' value, type := '(' string ')'):
- node names: one optional annotation ✔
- argument values & property values: one optional annotation ✔
- property keys: none ✘ (Drew's mcpx tests: assert the spawn happened in TestEnsureDaemonCancelledWhileWaiting #362)
- children blocks: none ✘ (Drew's CI: goreleaser workflow fails in setup on the next tag push — go-version-file points at go.work, deleted in Feb 2024 #344)
- multiple annotations anywhere: none — the grammar's
type?is
singular, everywhere. (Kuddle'sannotations: []shows at least one
implementation already models it as a list.)
3. Rust KDL landscape — fork candidates
Verified 2026-11-04 against crates.io + the repos' current sources.
kdl (kdl-org/kdl-rs) |
knuffel (tailhook) |
kaydle (Lucretiel) |
|
|---|---|---|---|
| Version / state | 6.7.1, actively maintained (repo pushed 2026-10; ~2.96M downloads) | 3.2.0, last release 2023-04 (stale) | 0.2.0, last release 2022-07 (unmaintained) |
| Role | Document parser + API; formatting/whitespace/comment-preserving parse & modify | Derive-based config decoder (serde-like Decode) |
Serde ser/de layer on top of the kdl crate |
| Spec versions | 2.0 default; 1.0 via v1 feature (sibling kdlv1 crate); converts documents between versions |
1.0 only | Whatever the underlying kdl crate did in 2022 (1.0 era) |
| Serde | Built in (serde default feature; de.rs/se.rs) |
Is itself a derive stack (not serde) | Is itself serde — superseded by kdl-rs's built-in serde |
| Search/query | KQL built in (query.rs — the KDL Query Language) |
None | None |
| Annotation model | KdlNode.ty: Option<KdlIdentifier>; KdlEntry.ty: Option<KdlIdentifier> (value); prop key = bare KdlIdentifier (no slot); KdlIdentifier = value+repr only |
Annotations not first-class (consumed as Rust types during decode); no document fidelity | Inherits kdl's AST of its era |
| Round-trip of unknown annotations | Preserved where representable (node/value ty + full format preservation); structurally impossible for prop keys / multiples — the parser cannot even hold them |
N/A (decode discards) | N/A |
| License | Apache-2.0 | MIT/Apache-2.0 | MPL-2.0 |
Also noted: kdlv1 (the split-out 1.0 implementation kdl 6.x wraps)
and Drew's own hygge (builder-only serializer; a candidate to revive
for the output side, §4d).
Recommendation: fork kdl-org/kdl-rs (kdl crate)
- It is the only candidate that is simultaneously: maintained,
dual-version, format-preserving, serde-complete, and query-equipped
(KQL matters for id: design: KDL as human presentation format + triples + ANSI graph SQL (SQL/PGQ) for ID data #5688's "searches efficiently" goal). - The fork's core change is contained: generalize
ty: Option<KdlIdentifier>→ annotation lists, and add annotation
slots where the AST has none (prop keys, children blocks). Every
other subsystem (dual parsers, fmt preservation, serde, KQL,
miette spans) carries over. - Starting from knuffel means rebuilding 2.0 support, document
fidelity, and a serializer from zero; kaydle is a layer, not a
parser, and is abandoned. Neither survives contact with §4a. - Apache-2.0; track upstream (spec evolution, test suites — including
the official KDL test suite the crate already runs) and upstream
what is upstreamable.
4. Fork design commitments (Drew, 2026-11-04)
(a) Compatibility is absolute. Every valid KDL 1.0 document parses
with its spec meaning unchanged; KDL 2.0 likewise, and future spec
versions are tracked. Extensions are additive: they never change
the meaning of a spec-valid document. (A document using extensions is
a superset document — a strict parser may reject it, and that is
accepted; the spec-valid subset always round-trips as plain KDL.)
(b) Universal, multiple, structured annotations. Generalize the
spec's value-only type hint to every part: node name, each
argument, property keys, property values, and the children
block (the #344/#362 asks), with multiple annotations per part
(Kuddle's annotations: [] precedent). Open design question, with
limit.kdl as the evidence base: annotation payloads — Drew's
practice packs structure into the annotation (#-/:-separated
parameters: (object#book#author:BrianGriffin),
(yes:yes:no:::bool)). Decide whether the payload stays an opaque
string (spec-shaped, maximally compatible) or gains a structured
sub-grammar in our dialect, and how either form decomposes into
triples under #5688.
(c) Performance and search efficiency are first-class. The
triples pipeline (#5688 §2) parses at ingest scale: streaming /
zero-copy parse paths where they matter, no format-preservation tax
on the hot path (make preservation opt-in per parse), and the
query story (KQL today; the SQL/PGQ graph layer in #5688) designed
against parsed-structure indexes rather than re-parse-per-query.
(d) Output beyond KDL text — the document-language direction.
Long-term this stops claiming to be KDL: it is our document
language with KDL as its default text form. Required renderers, in
#5688 §1.2's conversion-contract terms: KDL text (default), JSON,
YAML, and an LLM sentence rendering (a document rendered as
prose a model — or a person skimming — can read). Files are produced
"with an option": the same underlying document emits the requested
form. hygge (§1.3) is the in-house precedent for the builder/output
half.
5. Follow-on questions for the design pass
- Annotation payload grammar (§4b) — opaque vs structured; triple
decomposition of parameterized annotations. - Extension marking: does a document declare itself extended (a
header annotation? a version node?), so tooling can warn before a
strict-KDL consumer chokes? - Serde shape for annotation lists (attribute-style in derives?) and
how the kdl-rs serde layer exposes prop-key annotations. - Which pieces, if any, get proposed back upstream (the Discussions
show the maintainers' objection was use-case-shaped, and we now
have the use cases — but the fork does not block on upstream). - Benchmarks: upstream
kdlvs fork on the ingest corpus; the
acceptance bar for §4c.
— Filed by the KDL research pass, 2026-11-04. Sources: laptop
(~/git/code primary checkout), GitHub (issues/PRs/Discussions via
search + GraphQL), crates.io, spec grammars (SPEC_v1 + the KDL 2.0
IETF draft) — all read directly during the pass.
Activity
developing-today commentedon Nov 5, 2026
CODE-1441
dezren39 commentedon Nov 5, 2026
WS-I follow-on investigation (2026-11-04): "KDL 2 compact", hygge + parser landscape re-survey, fast serde alternates, and the fast-query form
Four threads from Drew's 2026-11-04 20:06 CST additions. Frame remains §4's commitments: KDL 1 compat absolute, universal + multiple annotations, performance and search as first-class goals. Cross-refs: #5688 (parent design — triples + SQL/PGQ), #5674 (postcard wire), #5675 (querying ID servers), #5681 (storage tiers).
0. "KDL 2 compact" — pinned down as a named requirement
The reading, stated as a requirement so it can be confirmed or corrected: the fork's baseline is KDL 2.0, and it defines a compact profile: a canonical minimal-whitespace emission of a document, used for stored / interchange copies (the search corpus, the provenance payload, content hashing), while the human form stays the pretty autoformat. If Drew meant something narrower (e.g. only "emit v2, never v1"), the profile below still stands on its own evidence; the open question is recorded at the end of this section.
What the spec allows. Nothing in KDL 2.0 defines a canonical or minimal form — formatting is implementation territory. But the 2.0 grammar is unusually minification-friendly, more so than 1.0:
;instead of newlines, and the last node in a children block needs no terminator even with}on the same line (node{foo;bar;baz}is legal 2.0).=in props is permitted but never required; zero is the minimum.(annotations)is legal in 2.0 — minification must therefore choose(foo), never be forced into it.What upstream's formatter can do — checked against the
kdl6.7.1 source (src/fmt.rs).FormatConfighas exactly four knobs:indent_level,indent(default four spaces),no_comments,entry_autoformate_keep. Every one serves pretty-printing. There is no compact/minified mode, and none can be configured into existence (autoformat always emits line-broken, indented documents). Conclusion: compact emission is a small new emitter mode in the fork — a serializer walk that joins nodes with;, emits one space only where the grammar requires separation, strips comments, and picks bare-vs-quoted identifiers minimally. It is not a parser change and does not touch §4a compatibility.Measured size deltas on our real documents (script minification of the actual files; rules: comments stripped, node-internal whitespace collapsed to single spaces,
;separators, no spaces around=or braces, strings preserved verbatim — reproducible in the follow-up pass):pkgs/mappy/migrations/limit.kdl(3,491 B on disk)pkgs/identity/config.kdl+configuration/embed/config.kdlCaveats: most of the win is comment + indentation removal, i.e. compact is a storage form, not an authoring form — the comments in
limit.kdlare design content and must survive in the authored copy. Multi-line string payloads cannot shrink below their content. (limit.kdl's torture-test tail also contains constructs outside the v2 grammar; the figure measures byte volume, not a round-trip promise for that file.)Why compact earns its place beyond bytes: canonical byte-stable text makes a document content-hashable and dedupable (composes with the treed-hash identity idea in
pkgs/id/README.original.md), and a search ingest that stores compact text scans ~⅓ fewer bytes before the parse even starts (thread 3).Open question for Drew (the uncertainty, stated plainly): is "compact" (a) this storage/interchange profile, (b) a v2-only emission policy ("KDL 2, compactly" as in the short version of the plan), or (c) both? Filed as (a)+(v2 baseline) pending correction.
1. hygge, read in full — and the parser landscape since
hygge (
developing-today/hygge, created 2022-02, last push 2023-12; v0.4.0; depends onkdl = "3.0.0"). Read end-to-end this pass:src/lib.rsis 780 lines.kdlv3 AST —KdlNodeBuilder(name/values/props/children),KdlValueBuilder(terse constructors:str/int/flt/y/n/nil),KdlValuesBuilder,KdlPropertiesBuilder— withbuild()producing realKdlNodes. It contains no parser (by design; the README defers input to knuffel/kdl-rs) and no serializer of its own — output is upstream'sDisplay.HashSetMap— a hash-consing register that deduplicates values by content hash intoRc<T>. As code it's a sketch; as a concept it's the direct ancestor of two things the fork wants anyway: string/value interning in the AST (§4c memory posture) and ID's content-hash identity thinking.&mut Stringplumbing (the source's own trailing comments list the ergonomics as unresolved — "unify str vs String", "&mut self vs Self"); the v1-shapedKdlValuemodel it wraps (thekdlcrate is three major versions past it, with a different numeric model); and it never touches annotations at all.The landscape since #5753's survey (verified this pass):
kdl(kdl-rs) 6.7.1kdlv1crate (the v4.7 lineage); v1⇄v2 conversion both ways; serde (src/de.rs/se.rs), KQL (src/query.rs), and theFormatConfigpretty formatter all in-tree. Current docs put MSRV at Rust 1.95 — noted, not blocking for us.ty: Option<…>on nodes/entries, bare prop keys, no children slot. The surgery is still exactly where §3 located it.knuffelkaydlekdlcrate.kdl6.x, typed decode by facet reflection. In real use (e.g. bearcove/tracey at facet-kdl 0.35 over kdl 6.5). The knus maintainer independently points at it as knus's successor.kdlAST exposes — i.e. it inherits the fork's annotation work for free once landed there.kdlyFork-base verdict: CONFIRMED, and strengthened. Every living Rust KDL effort now either is kdl-rs or sits on top of it (facet-kdl, kdlfmt, historically kaydle). The alternatives are v1-only (knus), maintenance-mode (knus), or abandoned (knuffel, kaydle). The annotation generalization remains a contained AST change in exactly one place — and it is the place the rest of the ecosystem already depends on, so the fork's improvements propagate to facet-kdl/knus-style consumers rather than stranding us on a private island.
2. Serde, but faster — the alternate-path shortlist
Baseline stands: the
kdlcrate's built-in serde (default feature) is the fork's serde story. What follows is what can sit beside it, feature-flagged, per Drew's "support serde but alternate performance versions maybe."'delifetimes,Cow, borrowed scalar views)bumpalo-style)SHAPEconst per type; format crates per format)memchr-class delimiter search plus thread 0's compact profile (fewer bytes to scan). Full structural-index SIMD is a research project, not a feature flag.Net: the credible "alternate performance version" is a parse-profile feature set (no-preserve + borrowed views + arena) inside the fork, with facet as an optional ergonomics layer and postcard as the binary form. There is no drop-in faster serde for KDL, and miniserde is not one either.
3. The fast-query form — what querying should run against
Framing note: #5688 §1.3 already rules that KDL text is not the query substrate. This thread answers the remaining question — what the substrate is, per tier — against §4c's "designed against parsed-structure indexes rather than re-parse-per-query."
(a) Rows at ingest (the triples / node-edge normalization). The
limit.kdlcomment sketch from 2023 (nodes: id, type, key, value/links/meta_links) is the same shape as #5688 §3.2's triple table (subject, predicate, object + statement linkage) with property-graph views over it. The decisive external evidence: every shipping SQL/PGQ implementation is exactly this architecture — property graphs defined as views over ordinary relational tables: Oracle 23ai (first commercial SQL/PGQ, in production), DuckPGQ (the CWI research extension bringing SQL/PGQ to DuckDB), and PostgreSQL's in-core work (below). Indexing is the known triple-store playbook: B-tree permutations (subject-predicate-object and its rotations) on the embedded engines; path queries via recursive CTE where PGQ isn't available. Ingest pays parse + decompose once; no query ever re-parses text.(b) A Postgres extension — split the idea in two, because the halves have opposite fates.
GRAPH_TABLEsyntax — a structural fact, re-confirmed by the PG19 episode: SQL/PGQ was committed to core for PostgreSQL 19 (Mar 2026) and reverted (Sep 2026) over catalog/dependency design, expected back no earlier than PG 20. If the platform itself had to go in-core and still slipped, an extension-side grammar is not a plan.kdldocument type + operators + GIN opclass: feasible but wrong target. The jsonb playbook (GIN's key-extraction contract is public and type-agnostic;jsonb_path_opsshows the compact-path-index shape) proves a document type can be indexed well in Postgres. But it buys document-local search in exactly one engine — and per design(id): serverless edition storage — D1 vs Turso vs both foridon Cloudflare Workers #5681/id: design: Querying local and remote ID servers v1 #5675, ID's server data plane is consolidating on Turso/SQLite, where a Postgres extension does nothing. If a Postgres-resident tier ever needs document-local KDL search, the cheaper move already exists: store id: design: KDL as human presentation format + triples + ANSI graph SQL (SQL/PGQ) for ID data #5688 stage-2's canonical JSON injsonband use the existing GIN stack. Do not build a kdl type. The Apache AGE experience is the standing warning for extension-side graph layers generally: queries as opaque strings the planner can't see into, sequential scans, no automatic label indexes.(c) SQLite / Turso tier. Same rows as (a) — that sameness is the point. Permutation B-tree indexes and recursive CTEs are native-shaped here; SQLite's JSONB storage (3.45+) covers the stage-2 JSON anchor if it needs local search; TursoDB is evolving quickly but offers no PGQ and no KDL surface, and the design should not wait on either. The answer is explicitly per-tier: one row model everywhere; the query surface differs — SQL/PGQ where an engine grows it (Oracle-class servers today; Postgres from PG20-era; DuckPGQ for analytics), a translated PGQ subset over CTEs on SQLite/Turso (the capability matrix is #5688 §3.3's deliverable), and KQL inside documents only.
(d) Native KQL over purpose-built indexes. Two independent problems. First, status: the QUERY-SPEC's current text describes "KQL
next" as unreleased, and the 2.0.0 release notes already flagged KQL as not finalized — the fork would be building store infrastructure on a draft. Second, shape: KQL is a CSS-selector-style document extraction language — node selection within a document, with no joins, aggregation, or graph patterns. It is the right tool where upstream already puts it (in-document selection, CLI/human surface, the fork inherits it free) and the wrong substrate for cross-document graph search. Building dedicated indexes for it duplicates (a) with a weaker model.Recommendation.
limit.kdlsketch, permutation indexes); KDL text — authored pretty, stored compact (thread 0) — is the provenance/interchange payload attached to the statement, never the thing queried.Experiments that settle the remainder (proposed for the follow-on pass):
limit.kdl-shaped generated corpus (10k / 100k / 1M statements in the character/predicate/object shape): (i) triple rows + permutation indexes, CTE and translated-PGQ arms; (ii) canonical-JSON-in-jsonb + GIN on a Postgres side instance (the (b) control arm); (iii) KQL over parsed documents with an in-memory index (the (d) control arm). Query set drawn from id: design: KDL as human presentation format + triples + ANSI graph SQL (SQL/PGQ) for ID data #5688's shapes: path patterns, annotation filters including parameterized payloads ((object#book#author:…)), qualifier joins. Measure ingest s/1k docs, index bytes, p50/p95 per query class.kdlvs fork profiles (preserve / no-preserve / no-preserve+arena) on the same corpus — this is also §5 question 5's acceptance bar, now with the corpus defined.Amendments this pass makes to §5's follow-on list
limit.kdlshape, generated at three scales) and the three-arm query bake-off above.— WS-I investigation pass, 2026-11-04. Sources: hygge repo read in full;
kdl6.7.1 source (src/fmt.rs, tree listing) and docs; KDL 2.0.0 release notes + QUERY-SPEC current text; kdl.dev implementations table; knus/knuffel/kaydle docs; facet author's own performance posts (figures attributed and caveated in-thread); miniserde/postcard docs and a third-party serialization micro-benchmark (flagged as such); PostgreSQL PGQ commit/revert coverage, DuckPGQ and Oracle 23ai documentation, PostgreSQL GIN documentation; size measurements computed from the laptop's real files.dezren39 commentedon Nov 5, 2026
🤖 Agent note · handed off