Stage 08
Respond — playback as a calibrated experiment, not an Instagram trick.
The temptation to play a caw at a crow and film what happens is the moment most projects break their ethics. Bidirectional dialogue is hard; cheap playback is easy. Don't confuse them.
The protocol, fixed before the session
Decide ahead of time what stimulus you will play, at what amplitude, from how far away, for how many seconds, with what observer in place to call a halt. Write it down. Sign it. Stick to it. A playback session that changes its protocol mid-run is no longer an experiment.
The six rules — recap
- No playback near active nests in breeding season.
- Never simulate alarm calls in public habitat.
- Limit sessions to under 90 seconds per location per week.
- Always observe response; stop on distress.
- Publish raw recordings, methods, and outcomes openly.
- When in doubt, listen more, broadcast less.
Full discussion on the ethics page. The rules apply to v0, v1, v5. They are not aspirational.
What the protocol looks like in practice
A typical v0 session: choose a target territory (no active nests within 100 m, confirmed by recent observation). Set up 20 m from the perch tree. Play a single exemplar — usually from cluster categories that don't carry alarm semantics (companion, food-discovery, territorial in a neutral neighborhood). Video both the speaker and the focal crow. Log timestamps for play-start, play-end, any approach, any departure, any distress posture. Halt at 60 seconds or on any distress signal.
Distress signals to watch for
- Tail-flicking + body-bobbing while staring at the speaker
- Repeated alarm calls in response (you accidentally broadcast a meaningful call)
- Flying directly at the speaker or recordist
- Group recruitment (multiple crows arriving and circling)
- Sudden silence + extended fixation
Any of these = halt, pack up, leave. Note it in the log. The session still counts as data; the negative-result halt is itself a result.
from crowlingo.playback import PlaybackSession, VideoObserver, halt
session = PlaybackSession(
stimulus="cluster_07_exemplar.wav", # "loud grunts" — non-alarm
max_seconds=60,
distance_m=20,
playback_db=70, # relative to ambient floor
observer=VideoObserver(
camera="gopro-1",
zone="speaker+focal_perch",
),
distress_callback=halt,
pre_registered=True,
protocol_doc="protocols/2026-05-16-cluster07.md",
)
session.run() # writes raw video, log, halt-reason to ./sessions/