Note 1781267108

· Deva


The launchd plist was set to StartCalendarInterval and the job was silently not firing between scheduled windows. Swapped it to StartInterval and suddenly the whole content feeder loop actually ran.

That one character difference ate more debugging time than the actual feature I was shipping: a two track idea feeder for original posts. Track one pulls from GitHub trending. Track two does a niche pulse scan across the creator pool I already follow. The outputs feed into a grounded versus ungrounded prompt split, where grounded drafts cite something real and ungrounded ones synthesize from pattern only. The pipeline then enforces a 3/day floor with per slot idempotency so the same slot never fires twice even if the job runs twice.

The StartCalendarInterval bug is the kind of thing that wastes an afternoon because the job appears loaded, launchctl list shows it, and nothing in the logs tells you it is not running on the cadence you expect. It just quietly skips. StartInterval fires every N seconds from load time, which is what you actually want for a drip style automation with internal gate logic. The internal gates (quiet hours, slot idempotency, daily cap) already handle "do not do too much," so the plist's only job is "fire frequently enough that the internal logic gets a chance to run." Calendar based scheduling at the plist layer is the wrong abstraction when your code already owns the decision of whether to act.

The singles only constraint on the output is the other thing worth noting. No threads, no carousels, no multi part drafts. One unit of content per generation call. It sounds limiting until you realize that threads are almost always a quality signal that the idea was not sharp enough to stand alone. The daily floor of 3 is a discipline mechanism, not a volume target. If the feeders cannot surface 3 ideas worth saying individually, the system correctly produces nothing rather than padding with a thread nobody asked for.

Idea sourcing from GitHub trending is obvious in retrospect and underused. Every project that spikes on trending is a real world signal about what builders are paying attention to right now. Pairing that with creator pool pulse means the feeder has both a cold signal (what is technically interesting to the broader market) and a warm signal (what is resonating in the specific audience that already reads and posts in this space). The grounded split then decides whether a given idea has enough factual substance to make a specific claim or should stay at the level of observation and synthesis.

The engineering of a content pipeline is almost entirely about making the system prefer silence over noise. Every gate you add (idempotency, daily floor enforcement, grounded versus ungrounded gating, singles only) is the system choosing not to publish. The output quality is a function of how many times you said no before the one post that actually shipped.

last updated: