Skip to content

Writing daily agent (portfolio content)

Watchable automation for one /writing article per calendar day — integrated with Ship, not WearLab.

Portfolio mechanics: portfolio/docs/WRITING_AUTOMATION.md (local sibling: ../portfolio/docs/WRITING_AUTOMATION.md).

Ops health agents: ops-agents.md.

Control plane

Where What you see
Ship board Initiative init-portfolio-writing-daily · ticket WRITING-DAILY
Agents strip Last run status for writing-daily
Receipts Each notify → timeline entry on WRITING-DAILY
Discord BACKFILL_READY, SUCCESS, STOP_NEED_TOPICS, failures
Woodpecker Optional cron portfolio-writing-poll on portfolio repo

Workflow stages (Ship ticket)

Portfolio WRITING_STATUS Ship stage waiting_on You do
SKIP_ALL_CAUGHT_UP done Nothing
BACKFILL_READY execute agent Open Cursor → Run backfill writing workflow
STOP_NEED_TOPICS queued topic_refill Refill writing topics
SUCCESS done Optional read on live URL
FAIL_* execute agent_failed Fix draft / QA / push

Notify hook

After writing:status, writing:catchup, or writing:finalize-batch, portfolio calls:

bash scripts/notify-ship-writing.sh BACKFILL_READY --missing 2 --items '[...]'

Env (local or Woodpecker):

  • SHIP_CI_WEBHOOK_SECRET — same secret as CI→Ship (ship_ci_webhook_secret)
  • SHIP_WRITING_WEBHOOK_URL — optional override (default https://ship.…/api/v1/agents/writing/notify)

Disable locally: SHIP_WRITING_NOTIFY=0 or WRITING_AUTOMATION=0

Automation toggle (Ship board)

Agents strip → Writing automation checkbox.

State Effect
ON (default) Woodpecker cron runs catch-up; Ship + Discord update
OFF Cron no-ops (AUTOMATION_DISABLED); WRITING-DAILY hidden from Needs you
Manual writing:finalize-batch in Cursor still works (notify uses force optional later)

API: GET/POST /api/v1/agents/writing/automation · config for portfolio: GET /api/v1/agents/writing/config (auth: X-Ship-CI-Secret).

Daily routine (Woodpecker cron)

09:00 / 18:00  Woodpecker portfolio-writing-poll → writing-catchup → Ship WRITING-DAILY updated
You open Cursor → Agent drafts → writing:finalize-batch → SUCCESS → Ship + Discord
Woodpecker deploys portfolio main → article live

Cursor (when waiting_on: agent)

  1. Ship shows WRITING-DAILY in Needs you / Agents strip.
  2. In portfolio repo: Run backfill writing workflow (see WRITING_AUTOMATION.md).
  3. Agent writes drafts → npm run writing:finalize-batch.
  4. Ship moves to done with live /writing/{slug} link.

Topic refill (when waiting_on: topic_refill)

Say refill writing topics in Cursor — see scripts/writing-prompts/topic-system.md.

Woodpecker cron (primary — no PC Task Scheduler)

Portfolio repo → Settings → Cron:

Name Schedule Effect
portfolio-writing-poll 0 9,18 * * * node scripts/writing-catchup.cjs on CI runner

Requires Woodpecker secret ship_ci_webhook_secret on portfolio repo (same value as infra).

Ship API

Endpoint Purpose
POST /api/v1/agents/writing/notify Portfolio / scripts report status
GET /api/v1/agents/runs Run history (?agent_id=writing-daily)

Auth: header X-Ship-CI-Secret (same as CI webhook).

Human gate before push (safety)

Default portfolio flow still runs QA + push on finalize-batch. For stricter control:

npm run writing:finalize-batch:dry   # merge + build + QA, no push
# you review → then push manually or re-run with push

Future: Ship action approve_writing_publish could gate push (not wired yet).

  • Golden path (feature work): ship-golden-path.md
  • Plane close on feature tickets: automatic on mark_done for PORT-* tickets