photo archive · cli

bairn

Photos and videos from your kid's daycare, kept onyour disk, in a form that outlives the vendor.

Your daycare uses Famly. Every week the educators post a stream of photos and short videos of your kid: lunch, the sand pit, a collage they made on Wednesday, the moment they tried a new word. Famly is built for the in-the-moment surfacing of that stream. It is not built to be a long-term archive of your child's first years.

bairn is a single Go binary that you run on your own machine, against your own household, with your own login. It pulls every photo and video the educators have posted, writes them into date-organized folders on your disk, and embeds the caption, the educator's name, the kid tags, and the date into each file's own EXIF and XMP metadata. Any photo viewer or future archival workflow can read those fields — today, and in twenty years.

The reason this matters is that an in-app feed is a handle to a service, not an artifact. When the company changes its mind about retention, sells to a different parent, deprecates the mobile app, or simply goes away, what you remember of your child's first three years of childcare goes with it.

FAMLYnursery feedphotos, captionsPULLBAIRNone binaryyour machineWRITEYOUR DISKdated foldersEXIF · XMP embeddedVENDORSURVIVESOUTAGESACCOUNT CLOSURESAPI CHANGES

disruption stops at the disk boundary

Once the bytes are on your disk with metadata embedded, none of those vendor outcomes touches the history. The file is the artifact, not a handle to a service.

flow · in

feed pages

Famly's parent-side GraphQL surface, walked one page at a time at the rate a single human user would naturally generate. Schema introspected from the live endpoint, types codegen'd, response shapes pinned by a drift baseline.

graphql · typed · introspected

discipline · posture

personal

One household, one operator, one set of credentials. No aggregation across families, no telemetry, no shared identifiers, no third-party calls. The binary doesn't know there is more than one of you.

one household · rate-limited

flow · out

files

JPEG and MP4 written to dated folders on your disk, with the caption, the educator's name, the kid tags, and the date embedded as EXIF and XMP. Optionally pushed into Immich after the on-disk write; the disk copy is always the source of truth.

disk first · immich optional

discipline · lifetime

archival

The file is the artifact, not a handle to a service. Open formats, standard metadata, no proprietary container. Readable in any year by any tool that has ever read a JPEG.

exif/xmp · open format · any year

Vendors fall along a spectrum when an outside party builds against their surface. The hostile ones forbid access in their terms and chase violations. The silent ones forbid access but ignore violations and tolerate the drift. A third group — the engaged ones — restricts usage in their terms, acknowledges the use case in support interactions, and points users toward self-service solutions. Famly is in that third group, and that's what makes bairnpossible: the surface is inspectable, the schema is introspectable, and the vendor's response when asked about export was to decline gracefully and point at the surface they already publish.

This isn't a license — it's reputational, and the reciprocal obligation is to stay careful: one household, one operator, the rate a human generates, no aggregation, no resale, no agent farm. See a progressive vendor stance for the agent-native future for the longer argument.

Three ways to run bairn, in increasing order of isolation from your day-to-day machine. Each release ships cosign-signed binaries, a CycloneDX SBOM per architecture, and a SLSA v1.0 provenance attestation, all verifiable against GitLab's OIDC issuer.

option a

Go install

go install gitlab.com/dunn.dev/bairn/cmd/bairn@latest

Build from source against your local Go toolchain. Best for contributors and anyone who already runs Go for other work. No signature verification — trust comes from the module proxy.

go 1.25+ · module-cached

option b

Prebuilt binary

curl -L -o bairn https://gitlab.com/dunn.dev/bairn/-/releases/permalink/latest/downloads/bairn-linux-amd64

Cosign-signed binary from the releases page. Pair the download with the matching .sig and verify against the GitLab OIDC issuer before running. The hardened option that doesn't ask you to install a Go toolchain.

linux/amd64 · linux/arm64 · darwin/arm64 · cosign

option c

Container image

podman pull registry.gitlab.com/dunn.dev/bairn/cli:latest

The OCI image is the prebuilt binary copied into a thin runtime layer — same cosign-signed artifact as option B, byte-for-byte. Best for cron on a homelab box where you don't want Go or a loose binary on disk. The image itself is cosign-signed by digest. Mount your archive and config in via -v at run-time.

oci · cosign-signed-by-digest · rootless-ok

A parent, co-parent, or household admin whose kid's daycare uses Famly and who wants a permanent local copy of every photo and video the educators post, with metadata that survives any future tooling change.

If your school doesn't use Famly, or if you're happy enough with how the mobile app surfaces history, bairnis not for you. It's also not multi-tenant — one binary, one household, one disk.

Not a privacy gateway. Every piece of context the vendor exposes lands inside the file you keep — that's the whole point of EXIF and XMP for archival. What happens to those files after you have them is your call. Not a scraping service either: one operator, the rate of one human, written to feel like a parent backing up their own photos because that's what it is.