music on atproto
plyr.fm
1# status maintenance workflow
2
3automated workflow that archives old STATUS.md content and generates audio updates.
4
5## what it does
6
71. **archives old content**: moves previous month's sections from STATUS.md to `.status_history/YYYY-MM.md`
82. **generates audio**: creates a podcast-style audio update covering recent work
93. **opens PR**: commits changes and opens a PR for review
104. **uploads audio**: after PR merge, uploads the audio to plyr.fm
11
12## workflow file
13
14`.github/workflows/status-maintenance.yml`
15
16## triggers
17
18- **manual**: `workflow_dispatch` (run from Actions tab)
19- **on PR merge**: uploads audio after status-maintenance PR is merged
20
21schedule is currently disabled but can be enabled for weekly runs.
22
23## how it determines the time window
24
25the workflow finds the most recently merged PR with a branch starting with `status-maintenance-`:
26
27```bash
28gh pr list --state merged --search "status-maintenance" --limit 20 \
29 --json number,title,mergedAt,headRefName | \
30 jq '[.[] | select(.headRefName | startswith("status-maintenance-"))] | sort_by(.mergedAt) | reverse | .[0]'
31```
32
33everything merged since that date is considered "new work" for the audio script.
34
35### handling reverted PRs
36
37if a status-maintenance PR is merged then reverted, it still appears as "merged" in GitHub's API. this can cause the workflow to think there's no new content.
38
39**workaround**: temporarily add an exclusion to the jq filter:
40
41```bash
42| select(.number != 724) # exclude reverted PR
43```
44
45remove the exclusion after the next successful run.
46
47## archival rules
48
49**line count targets**:
50- ideal: ~200 lines
51- acceptable: 300-450 lines
52- maximum: 500 lines (must not exceed)
53
54**what gets archived**:
55- content from months BEFORE the current month
56- if today is January 2026, December 2025 sections move to `.status_history/2025-12.md`
57
58**how archival works**:
591. CUT the full section from STATUS.md (headers, bullets, everything)
602. APPEND to the appropriate `.status_history/YYYY-MM.md` file
613. REPLACE in STATUS.md with a brief cross-reference
62
63archival means MOVING content, not summarizing. the detailed write-ups are preserved in the archive.
64
65## audio generation
66
67### pronunciation
68
69the project name is pronounced "player FM". in scripts, write:
70- "player FM" or "player dot FM"
71- never "plyr.fm" or "plyr" (TTS mispronounces it)
72
73### terminology
74
75plyr.fm operates at the ATProto protocol layer:
76- say "ATProto identities" or "identities"
77- never "Bluesky accounts"
78
79Bluesky is one application on ATProto, like plyr.fm is another.
80
81### tone
82
83dry, matter-of-fact, slightly sardonic. avoid:
84- "exciting", "amazing", "incredible"
85- over-congratulating or sensationalizing
86
87### script structure
88
891. opening (10s): date range, focus
902. main story (60-90s): biggest feature, design decisions
913. secondary feature (30-45s): if applicable
924. rapid fire (20-30s): smaller changes
935. closing (10s): wrap up
94
95## inputs
96
97| input | type | default | description |
98|-------|------|---------|-------------|
99| `skip_audio` | boolean | false | skip audio generation |
100
101## secrets required
102
103| secret | purpose |
104|--------|---------|
105| `ANTHROPIC_API_KEY` | claude code |
106| `GOOGLE_API_KEY` | gemini TTS |
107| `PLYR_BOT_TOKEN` | plyr.fm upload |
108
109## manual run
110
111```bash
112gh workflow run "status maintenance" --ref main
113```
114
115with skip_audio:
116```bash
117gh workflow run "status maintenance" --ref main -f skip_audio=true
118```
119
120## troubleshooting
121
122### workflow sees wrong time window
123
124check which PR it's using as the baseline:
125
126```bash
127gh pr list --state merged --search "status-maintenance" --limit 5 \
128 --json number,title,mergedAt,headRefName
129```
130
131if a reverted PR is polluting the results, add a temporary exclusion.
132
133### audio has wrong terminology
134
135check the terminology section in the workflow prompt. common mistakes:
136- "Bluesky accounts" should be "ATProto identities"
137- "plyr" should be "player FM" (phonetic)
138
139### STATUS.md over 500 lines
140
141the archival step should handle this, but verify:
142- december content should be in `.status_history/2025-12.md`
143- only current month content stays in STATUS.md