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