Set it and forget it: the slot-queue model in forge-social

forge-social v0.4.0 ships a second scheduling model alongside the existing explicit-timestamp approach. Instead of deciding when each post goes out before you write it, you define a weekly publishing rhythm once and let the queue do the rest.

The problem with explicit timestamps

Model 1 has been in forge-social since v0.1.0: set a scheduled_at timestamp, and the scheduler publishes the post at that exact time. It works well for event-driven content — a release announcement, a conference post, something tied to a specific date.

It works less well for a steady content cadence. If you want to publish three times a week, every week, you have to assign a timestamp to every post before you queue it. That means deciding in advance when each piece goes out, which is rarely how writing actually works.

The slot-queue model

A PublicationSchedule defines recurring weekly time slots for a credential:

social schedule create \
  --credential <id> \
  --slot "monday 09:00 Europe/Copenhagen" \
  --slot "thursday 09:00 Europe/Copenhagen"

Each slot specifies a weekday, a time (HH:MM), and an IANA timezone. One schedule per credential.

Posts queued for that credential have no scheduled_at. They wait in a FIFO queue. When a slot fires, the scheduler dequeues the oldest queued post and publishes it. If the queue is empty when a slot fires, it skips silently — no errors, no noise.

The full loop from zero:

# 1. Create credential record
social credential create --platform mastodon --name "My account"

# 2. Connect via OAuth (open the printed URL in a browser)

# 3. Create schedule
social schedule create \
  --credential <id> \
  --slot "monday 09:00 Europe/Copenhagen" \
  --slot "thursday 09:00 Europe/Copenhagen"

# 4. Queue posts — no timestamps, just content
social post queue --credential <id> --body "First post in the queue"
social post queue --credential <id> --body "Second post — goes out Thursday"

That's it. Posts go out in order on Monday and Thursday at 09:00 Copenhagen time.

Catch-up

If the server restarts and misses a slot, it catches up on the next tick. One post per missed slot, capped at len(slots) per tick — so a long outage never floods the platform with a backlog at once. Queued posts are never lost; they're persisted in SQLite alongside the schedule's last-tick timestamp.

Pausing without losing the queue

social schedule pause --credential <id>

Slots stop firing. Queued posts stay in the queue. Resume with social schedule resume when ready.

CLI parity

forge-cli v0.7.0 ships full CLI coverage for everything in forge-social. Every MCP operation is also available from the terminal:

social post create / list / get / publish / archive / delete
social post queue
social credential create / list
social schedule create / show / pause / resume / delete

The social post queue command is a shorthand for create with status: queued — one command, no flags for timestamps.

MCP tools

Five new MCP tools cover schedule management:

  • create_publication_schedule
  • get_publication_schedule
  • update_publication_schedule
  • list_publication_schedules
  • delete_publication_schedule

The existing post and credential tools are unchanged. The slot-queue model is additive — explicit scheduled_at posts continue to work exactly as before.


forge-social v0.4.0 and forge-cli v0.7.0 are available now.