/
/
/
Ansible role that deployes services on my runner machine
1# Atmosphere tuning. Lives beside cues.yml in the media root so it can be
2# changed between sessions without an Ansible run or a rebuild.
3#
4# Everything here is a threshold with no knowable-right value until several
5# real sessions have been watched. Start in observe mode, read cues.jsonl
6# afterwards, then adjust.
7
8# observe detectors run, the timeline records, nothing plays. <- start here
9# live as observe, and cues actually fire.
10# off the atmosphere layer does not run at all.
11#
12# Overridable with DND_ATMOSPHERE_MODE, which is the one thing worth flipping
13# without editing this file.
14mode: observe
15
16effects:
17 # off | sparse | normal | dense
18 #
19 # sparse fires only on words from the cue's own name, with a long cooldown.
20 # normal adds the upstream Freesound synonyms -- which is what catches
21 # "cavern" for cave_drip, and also what catches the occasional artefact of
22 # how a sound was recorded. Drop to sparse first if it is too busy.
23 sensitivity: normal
24
25ambience:
26 enabled: true
27 # No change within this of the last one, whatever anything says. A bed that
28 # swaps twice inside a minute is worse than any wrong choice it is correcting.
29 hard_floor: 90
30 # Past the floor, still held unless the evidence is good. A DM setting a
31 # battlemap bypasses both: that is an explicit human signal about the scene.
32 soft_hold: 180
33 # Evaluated on this cadence even when no trigger word appears, because a
34 # scene can change with nothing to match on -- "the trees give way" is a
35 # transition containing no cue word at all.
36 period: 60
37 min_score: 2.0
38
39# Each is a question with a right answer rather than a judgement of mood, which
40# is why they are worth more than their sound. Start with the four sharpest and
41# add from what the timeline actually shows.
42#
43# Also available: character_down, death_save_failed, creature_dies,
44# critical_hit, spell_cast, lock_forced
45events:
46 - natural_20
47 - natural_1
48 - level_up
49 - initiative
50
51# Collapses a burst: a paragraph saying "cave" six times is one evaluation, not
52# six model calls to reach one decision.
53tick_debounce: 2.0
54# How much quiet from the DM counts as the end of a paragraph, which is when
55# the "what did that do, and did it matter?" question runs.
56paragraph_gap: 3.5
57
58# Small and fast for per-tick classification; the larger one only for scene
59# selection, where the latency does not matter and the judgement does.
60# Every judgement the agent makes runs on this -- `ambience_model` below is
61# parsed and never used, so this is the whole live half.
62#
63# **Moved 8b -> 14b on 2026-09-01, measured.** 87 windows from the E25 hour,
64# ground truth from the captions, 2 real rolls:
65#
66# qwen3:8b nothink 30 false positives 0.79s median
67# qwen3:14b nothink 9 false positives 0.98s median
68# qwen3:8b THINK 5 false positives 7.88s median
69#
70# A 3.3x cut in false fires for 0.19s. The effect gate also improved (10/10
71# against 9/10 on a judged set). Memory measured with Whisper resident:
72# 14b + distil-large-v3 is ~10.4 GB of the 12 GB card.
73event_model: qwen3:14b
74ambience_model: qwen3:14b
75