--- name: schedule-week description: > Turn a content plan — often produced by the content-calendar or repurpose skills — into real scheduled placements on the real calendar: parse the plan, map every row to a connected channel, validate each post against live platform rules, propose the full week's schedule, and book it. Covers LinkedIn, X (Twitter), Instagram, and Facebook. Use when the user says "schedule my week", "schedule this plan", "put my calendar on the calendar", or "schedule these posts". Requires the Inklate MCP connection. Reads social-context.md when present for cadence and voice. The receipt is the week as a table of real scheduled times and post IDs, verified against the queue. metadata: version: 1.0.0 topics: [planning, publishing] examplePrompt: "Schedule this two-week content plan across my channels" pairsWith: [content-calendar, repurpose] mcpTools: [preflight_post, schedule_placements, list_posts, get_job_status] --- Take a content plan off the page and onto the real calendar: every row becomes a validated post with a confirmed scheduled time on a real channel. ## Connection check 1. Call `list_organizations` before reading the plan. 2. If it fails or the Inklate tools are absent, tell the user to connect at `https://inklate.com/skills/connect?ref=skills-schedule-week` and STOP. 3. If multiple organizations exist, ask which one owns this calendar. All times and channels below are scoped to that organization. ## Context Read `social-context.md` (project root, then `.agents/social-context.md`) if present. `## Cadence` is the reality check against overstuffed plans, `## Platforms` resolves ambiguous channel names in the plan, and `## Voice` / `## Never` govern any content adjustments you make while fixing violations. Proceed without it if absent. ## Workflow 1. **Parse the plan.** Read the plan table or list the user provides. Extract per row: content (or a pointer to a draft), target channel(s), and intended day/time. Flag rows you cannot parse instead of guessing. 2. **Map rows to channels.** Match each row's platform to a connected channel. Rows targeting unconnected platforms get flagged and set aside — never silently dropped, never scheduled to a wrong channel. 3. **Create the posts.** For each mapped row, create the post with its content and sync per-channel variants (as in the `publish` skill). Keep a running row-to-post-ID map. 4. **Preflight everything.** Call `preflight_post` on each post. Auto-fix what is fixable, surface judgment calls to the user in one consolidated batch (not one interruption per post), and re-run until each post is green or explicitly parked. 5. **Build the proposed schedule.** Convert the plan's intended times into concrete datetimes in the organization's timezone, then apply the constraints: - Spacing: no two posts on the same channel within 3 hours — when the plan violates this, nudge the later post and note the nudge. - Existing queue: check `list_posts` for already-scheduled placements in the window so the new week doesn't collide with them. - Rows with a day but no time get a sensible default for that platform, marked as your suggestion. - Past times are an error, not a nudge: flag any row whose intended time has already passed. 6. **Approval gate.** Present the entire proposed week as one table — day, time (org timezone), channel, content summary, preflight status — before anything is booked. Scheduling posts is a real-world action: get an explicit yes on the whole table, or apply the user's edits and re-present. Never book a partial week on an implicit go-ahead. 7. **Book it.** On approval, call `schedule_placements` with the confirmed placements. 8. **Verify.** Call `list_posts` for the scheduled window and confirm every placement appears with the right time and channel. For any placement still processing, call `get_job_status` and report the real job state. Discrepancies between what was booked and what the queue shows are reported immediately, not glossed. 9. If the plan spans more than one week, book week by week — approve and verify week one before proposing week two, so a mid-plan change of mind never strands half-booked placements. ## Quality bar - Never schedule a post that is not preflight-green; parked posts appear in the receipt as unscheduled with the reason. - All times are stated and booked in the organization's timezone; if the plan's times imply a different timezone, resolve the conflict with the user before proposing. - Spacing rule is hard: no two posts on one channel within 3 hours. Nudges made to satisfy it are listed explicitly. - The proposed-schedule table shown for approval must match what `schedule_placements` is called with — no drift between preview and booking. - Verification via `list_posts` is not optional; the receipt reflects the queue's reality, not the request you sent. - If the plan exceeds the cadence in social-context.md by more than double, say so once before proposing — then respect the user's call. - Every placement in the receipt carries its post ID so the user can unschedule or edit any single slot later without archaeology. ## Receipt End with the booked week as verified against the queue: | Day | Time (org tz) | Channel | Post ID | Content | Status | | ---------- | ------------- | --------- | ----------- | ---------------------------------- | ----------------------- | | Mon Jul 20 | 9:00 AM | LinkedIn | post_abc123 | "Why we killed our roadmap…" | scheduled | | Mon Jul 20 | 1:00 PM | X | post_abc124 | Thread: roadmap lessons (6 tweets) | scheduled | | Wed Jul 22 | 10:00 AM | Instagram | post_abc125 | Carousel: 5 lessons | processing (job queued) | Below the table: total placements booked, any rows parked with reasons, any spacing nudges applied, and the `get_job_status` state for anything not yet confirmed on the calendar. Every row in this table was verified against `list_posts` — it is the queue's account of the week, not the request's.