Skip to main content

Publish your first index

An index is the unit you expose. You decide what goes into it, what the network is allowed to learn about it, and who may query it.

Define the index

gnarl.yaml
index:
name: imagery
source:
path: ./corpus/imagery
include: ["**/*.json", "**/*.tif.meta"]
fields:
- name: title
type: text
analyzer: standard
- name: captured_at
type: datetime
- name: footprint
type: geo_shape
- name: sensor
type: keyword

# What peers may learn from the manifest. Everything else stays local.
expose:
fields: [title, captured_at, sensor]
summary: [doc_count, time_range, bbox]

policy:
networks: [acme-internal]
rate_limit: 40/s
require_signed_queries: true

Build it

gnarl index build imagery
▸ scanning ./corpus/imagery
▸ indexed 48,219 documents · 14.2 GB source · 4.9 GB index · 3m11s
▸ manifest sha256:7f2c…9ab1 · signed by n1qh7f…c2a8

Inspect the manifest before you publish

This is what peers will see. Nothing else leaves the node.

gnarl manifest show imagery
{
"index": "imagery",
"node": "n1qh7f2m9x8p4vd6kkzq3r7wjn5tbc2a8",
"doc_count": 48219,
"fields": ["title", "captured_at", "sensor"],
"summary": {
"time_range": ["2019-03-01T00:00:00Z", "2026-07-28T00:00:00Z"],
"bbox": [-124.7, 24.5, -66.9, 49.4],
"sensor": ["landsat-8", "sentinel-2", "planetscope"]
},
"signature": "ed25519:9c41…2f7e"
}

Publish

gnarl index publish imagery

Peers now route matching queries to you. Everything not listed under expose remains invisible — the network knows you can answer questions about Landsat scenes from 2019 onward, and nothing more.

Verify end to end

From a different node on the same network:

gnarl search "cloud-free scene over puget sound" --explain
▸ planned 6 nodes matched manifest predicates (of 12 peers)
▸ fan-out 6 asked · 6 answered · 0 timed out
▸ merged 124 hits · 128ms · all signatures verified

Keeping it fresh

gnarl index watch imagery # rebuild incrementally as files change
gnarl index refresh imagery # one-off rebuild, republishes the manifest

Next