Skip to content

What were the squirrels up to?

The 2018 Central Park Squirrel Census is attributed to The Squirrel Census. Its portal metadata declares no license; review the NYC terms before redistributing a snapshot. The four-row offline sample is synthetic, not the population. Counts below are computed against that sample; never extrapolate the eight-note interpretation to all squirrels.

You need Bun for the small normalization/verification scripts, ribbit installed on PATH, and configured local-small object-capable model for interpretation. For live acquisition you also need curl, jq, and sha256sum or shasum. npm installation does not include example files: clone https://github.com/funsaized/ribbit at a reviewed revision to get examples/squirrel-report/, examples/flows/squirrel-report.yaml, and the sample. Start at the checkout root.

bun examples/squirrel-report/normalize.ts fixtures/tutorials/squirrels/sample.json > squirrels.jsonl
ribbit where has_note --args-json '{"equals":true}' --input jsonl --file squirrels.jsonl --output records > noted.records

Expected output: four normalized rows; noted.records has the v1 header and three rows, with independent row IDs despite duplicate unique_squirrel_id values. Inspect age: null versus absent age, and the retained activity flags. The normalizer computes exact counts; use it on a frozen snapshot, not a model answer.

For a live snapshot, run bash examples/squirrel-report/acquire.sh squirrels.raw.json; save its checksum and retrieval date with the raw bytes. The script requests ordered :id pages with a six-page cap. Pages are not transactional; recheck counts/IDs on the frozen response. Then normalize squirrels.raw.json in place of the sample above. Do not substitute unique_squirrel_id for the row ID; duplicates exist in the live dataset.

Select a deterministic bounded sample, retain it, then annotate without replacing original values:

ribbit take 8 --input records --file noted.records --output records > sample.records
ribbit map 'Extract one observation; quote an admitted note verbatim.' \
  --annotate observation --schema examples/squirrel-report/observations.schema.json \
  --input records --file sample.records --profile local-small --max-requests 32 --total-ms 120000 \
  --output records > annotated.records

Required properties: observation holds a schema-constrained behavior, human-involvement flag, and quote; value, ID and source remain unchanged. The entire original record, including both note fields and activity flags, reaches the model. The supplied sample makes three requests; eight live notes can consume up to 32 requests with repairs/retries. Use --max-requests 32 for that worst case (or reduce the sample), and allow sufficient total time. Provider timeout/size limits still apply. Check exit status before accepting a partial stream. Do not claim a quote is real merely because it matches a JSON schema; verify it against the admitted originals.

The equivalent flow consumes the normalized record stream and shares one invocation budget:

ribbit flow run examples/flows/squirrel-report.yaml --input jsonl --file squirrels.jsonl \
  --max-requests 32 --total-ms 120000 --output records > flow-observations.records

Required properties: exact where selects nonempty notes, take caps eight, and annotation-mode map preserves originals. A field report may use an explicitly routed reduce on only the saved sample, then cite admitted IDs and verbatim quotations; verify it with bun examples/squirrel-report/verify-report.ts report.md sample.records. Keep raw response, normalized JSONL, sampled records, annotations, report, and its stderr separately. The offline test checks reference/quote membership and exact sample counts; no captured model prose is presented as a deterministic expected output.

Produce the report with code, not a model-generated total. The reporter rejects quotations absent from their cited notes and keeps population counts separate from the small qualitative sample:

bun examples/squirrel-report/report.ts squirrels.jsonl annotated.records > report.md
bun examples/squirrel-report/verify-report.ts report.md sample.records

Expected output: for the supplied four-row synthetic sample, report.md says Population: 4 captured rows and cites three admitted IDs. The verifier reports three references. Required properties: the captured-row totals come from exact arithmetic; no quoted text is accepted solely because a schema matched. If you instead write a model-synthesized report using reduce, verify that output the same way and retain both versions.