Skip to content
scsiwygest. ‘26
Sign in
get startedmcpcommunityapiplaygroundswaggersign insign up
project-state·Publishing and external comms — Slack, Gmail, blog, website28 May 2026David Olsson
project-state

Publishing and external comms — Slack, Gmail, blog, website

What you need: A populated project-state/ substrate with surfaces configured in manifest.yaml.


project-state generates artifacts — status reports, meeting notes, blog posts, milestone summaries. Those artifacts need to reach people. Surfaces are the external systems where artifacts get delivered. Five are supported: Slack, Gmail, Google Calendar, blog (scsiwyg), and project website.

The governing principle across all five: the system does the work of generating the artifact. A human does the work of deciding to send it.

The five surfaces

Each surface is configured in manifest.yaml:

surfaces:
  slack:
    enabled: false
  gmail:
    enabled: false
    always_draft: true
  google_calendar:
    enabled: false
  blog:
    enabled: true
    site_slug: "project-state"
    site_url: "https://www.scsiwyg.com/project-state"
    publication_review_required: false
  website:
    enabled: true
    framework: "nextjs"
    hosting: "vercel"
    production_url: "https://project-state-docs.vercel.app"
    require_review_for_public: false

Surfaces with enabled: false are ignored by the notifier and the orchestrator. Enable them when your project is ready for that channel.

Gmail is always draft

This is a design constraint, not a configuration option. The always_draft: true field exists in the schema, but there is no always_draft: false path in the code. Every email artifact project-state produces lands in your Gmail drafts folder. You review, edit if needed, and press send yourself.

The reason is blast radius. A misconfigured reporting matrix entry or a hallucinated status report is harmless as a draft. Sent to a steering committee, it's a problem. The cost of reviewing a draft is 30 seconds. The cost of retracting a sent email is a conversation nobody wants to have.

When project-state creates a Gmail draft:

Created Gmail draft:
  To:      jane@acme.com, steering-committee@acme.com
  Subject: Weekly Status — 2026-W22
  Body:    [generated from project-status-reporter]

→ Review in Gmail before sending.

Slack auto-posts

Slack is the exception to the review-before-send rule. Messages post directly to the configured channel. The reasoning: Slack is ephemeral by nature. A status update in a channel is low-stakes — it can be corrected with a follow-up message. The channel is configured in the manifest, so the audience is known and bounded.

yaml
surfaces:
  slack:
    enabled: true
    channel: "#project-updates"

When a skill routes an artifact to Slack:

Posted to #project-updates:
  Weekly Status — 2026-W22
  Phase: 04-release | Health: green
  [milestone summary table]

If you want review-before-post on Slack, disable the surface and use Gmail drafts instead.

Blog with audience tiers

The blog surface publishes to scsiwyg. Three visibility levels control who sees what:

VisibilityAudienceUse case
publicAnyone with the URLRelease notes, documentation, announcements
journalTeam members onlyWeekly status, retrospectives, internal updates
Draft (unpublished)Author onlyWork-in-progress, review pending

The publication_review_required flag in the manifest controls whether skills can publish directly or must create drafts:

yaml
blog:
  publication_review_required: true   # skills create drafts only
  publication_review_required: false  # skills can publish directly

When review is required, the flow is:

  1. Skill generates the post content
  2. Skill creates a draft on scsiwyg
  3. You review the draft at scsiwyg.com/project-state/[slug]
  4. You publish when satisfied

When review is not required, the skill publishes immediately. This is useful for internal journal posts (weekly reports) where the overhead of review isn't justified.

Project website

The website surface deploys a Next.js application that renders the substrate as a live reference site. Documents promoted to documents/published/ appear as pages. Milestones, risks, and decisions are accessible through the dashboard views.

yaml
website:
  enabled: true
  framework: "nextjs"
  hosting: "vercel"
  production_url: "https://project-state-docs.vercel.app"
  auto_deploy_on_publish: true
  require_review_for_public: false
  default_visibility: "public"

The auto_deploy_on_publish flag means that when project-website-publisher generates new pages, they deploy automatically. With require_review_for_public: true, generated pages land as drafts in the website's content directory, and you deploy manually.

The website reads from the same substrate as the kanban dashboard. The difference is audience: the kanban is for the team (localhost), the website is for stakeholders (public URL).

Calendar holds

Google Calendar integration proposes meeting holds — it does not create confirmed events. When the orchestrator identifies an upcoming steering committee meeting or a deadline-driven review:

Proposed calendar hold:
  Title:    SC Meeting Prep — Q2 Claim Review
  When:     2026-07-15 10:00-11:00
  Calendar: project-acme

→ Confirm in Google Calendar to finalize.

The hold appears as a tentative event. You confirm, reschedule, or delete it.

The notifier

project-notifier is the central routing skill. It reads the reporting matrix and the manifest's surface configuration to determine where each artifact goes. When a generator skill (like project-status-reporter) produces output, the notifier:

  1. Reads the matrix entry to find the target surface
  2. Checks if that surface is enabled in the manifest
  3. Routes the artifact to the appropriate surface API
  4. Logs the delivery to activity.ndjson

The notifier does not generate content. It takes a finished artifact and puts it where the matrix says it should go. If the target surface is disabled, the notifier logs a skip and moves on — no error, no retry.

The pattern across all surfaces

The review model varies by surface, but the architecture is consistent:

  1. A reporting matrix entry defines what artifact, for which stakeholder, on which surface
  2. A generator skill produces the artifact content
  3. The notifier routes it to the surface
  4. The surface's review model determines whether it goes live immediately or waits for human approval

Gmail always waits. Slack never waits. Blog and website are configurable. Calendar proposes but doesn't confirm.

Next step

Surfaces deliver artifacts to the outside world. But the project also moves through lifecycle phases, and transitions between phases have gates that enforce readiness. Phase transitions and gates shows how the five phase presets work and what happens when a gate blocks your transition.