Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Extensions

Extensions attach domain-specific data to generic observations without changing the event protocol or requiring every node to understand that data.

Envelopes

An observation stores a map from namespaced extension IDs to versioned JSON envelopes:

{
  "org.example.observations/rainfall": {
    "version": 1,
    "data": {
      "millimeters": 12,
      "condition": "steady"
    }
  }
}

Every envelope has a stable extension ID, a positive version, and an object-shaped data value. An ID must contain /, have non-empty text on both sides, use a namespace containing . or :, and contain no whitespace. Reverse-domain namespaces are conventional but not centrally registered:

org.example.observations/rainfall
com.example.community/trail-condition

An extension publisher must not change the meaning of an existing ID and version. Publish an incompatible interpretation under a new version.

Opaque compatibility

Every node validates the envelope structure. A node does not need a manifest to store, export, rebuild, or forward a valid envelope. Unknown IDs, unsupported positive versions, and unknown keys remain opaque data.

A local manifest adds typed adapter behavior:

  • Signal input profiles
  • Signal detail and creation-receipt templates
  • Dedicated Grist columns and edit conversion
  • Numeric measures for grouped Signal search
  • Extension support in flock metadata

Manifests are local configuration, not federated schemas. Flock metadata advertises only extension IDs and versions. Each receiving node independently chooses which manifests to trust and install. Advertised support never gates replication.

Removing a manifest does not remove extension data. Its envelopes become opaque again and continue to be stored and forwarded.

Install manifests

Birdd loads no extensions implicitly. Configure an ordered list of strict TOML manifest files and restart the process:

[extensions]
manifests = ["extensions/rainfall.toml"]

Relative paths are resolved from the directory containing birdd.toml. Birdd validates the complete registry before opening the node. Invalid manifests, duplicate extension IDs or profile names, generated Grist column collisions, and invalid measure references prevent startup.

The source tree includes optional bird examples:

  • extensions/birds-taxon.toml projects common_name as a Species column.
  • extensions/birds-count.toml provides a positive count input profile, Count column, and seen measure.

Nix packages install these examples under share/birdd/extensions. See Node configuration for standalone and NixOS paths.

Create opaque data

The CLI can create arbitrary envelopes whether or not their manifests are loaded:

birdd --config birdd.toml create "Creek flooding" \
  --extension '{"org.example.observations/water":{"version":1,"data":{"depth_cm":12}}}'

The argument must be a JSON object mapping extension IDs to complete envelopes. A manifest is needed only for typed adapter behavior.

Disclosure

Audience projection copies complete extension envelopes. Field declarations in a local manifest are not a privacy filter. Restricted audiences can include all extensions or exact IDs, while public audiences always include every envelope. Review the actual envelope data before publishing it.

The authoritative projection behavior is in Federation and audiences, and accepted configuration values are in Node configuration.

Continue with Authoring extensions, Signal integration, or Grist integration.