The dev diary job felt cursed today–skipping with “no Glad Labs activity” while PRs merged left and right–because our worker container lacked the gh and git binaries. The _run_subprocess calls were returning FileNotFoundError, and since the failures were swallowed at logger.debug level, both collectors just returned empty lists. We rewrote services/topic_sources/dev_diary_source.py to talk to the GitHub REST API via httpx instead of shelling out, removing the dependency on those binaries and the .git directory entirely. We also added a gh_repo app_setting so operators on a fork can point the diary at their own repo without code changes. We upgraded all silent failure paths to logger.warning for network and JSON errors so Loki actually picks up future regressions instead of swallowing them. (PR #294)
Beyond the diary fix, the brain is getting a cleanup. We implemented batching for gate pending summaries and demoted per-flip Telegrams to Discord to cut down on noise. We added a new brain/gate_pending_summary_probe.py that coalesces alerts into a single “N posts pending” message once per hour when the queue has been non-empty past a grace window (PR #292). To prevent the “fat finger double-tap” of poindexter post create from spawning duplicate gate trees, we added a posts.cli_idempotency_key column and tuned the CLI to reject duplicates within a 30-minute window (PR #290). We also implemented auto-expiry for pending gates with a configurable gate_pending_max_age_hours (default 7 days) to keep review queues from rotting, and fixed the DevTo cross-post service to treat a 422 “Canonical url has already been taken” response as a successful hit instead of an error (PR #291, PR #289). The test suite received a refresh to match the new batch commands, and we expanded coverage on the topic ranking module to hit the edge cases the happy-path suite was skipping (PR #287, PR #286). A code quality audit ran, flagging 10 medium-severity findings that we’ll triage next (PR #281).
We traded shell dependencies for a clean API client, and with that silence gone, we can finally see the data coming in. The idempotency keys and auto-expiry rules give us a better handle on operator error rates and queue hygiene. From here, the diary feed is live again, and the brain is finally batching the noise so we can focus on the signal.
Auto-compiled by Poindexter from today’s commits and PRs.
Sources
- https://github.com/Glad-Labs/glad-labs-stack/pull/294
- https://github.com/Glad-Labs/glad-labs-stack/pull/292
- https://github.com/Glad-Labs/glad-labs-stack/pull/290
- https://github.com/Glad-Labs/glad-labs-stack/pull/291
- https://github.com/Glad-Labs/glad-labs-stack/pull/289
- https://github.com/Glad-Labs/glad-labs-stack/pull/287
- https://github.com/Glad-Labs/glad-labs-stack/pull/286
- https://github.com/Glad-Labs/glad-labs-stack/pull/281

