Skip to content

Site pipeline

PULSE can run a company website’s content loop end to end: it writes blog posts and publishes them to the site’s Hugo repository, audits the live site every day, and opens pull requests that fix what the audit finds. Runink runs its own site this way. Each deployment points PULSE at its own site. There are no defaults that name Runink.

Blog posts to your Hugo site

How a post gets there

  1. A post is written. Either the social engine drafts one blog article per active campaign per day, or you approve blog-channel content yourself.
  2. It is scheduled. The social engine schedules its draft two hours ahead. That window is a chance to cancel it on the Schedule screen before the worker dispatches it.
  3. It is published over git. PULSE renders the content as a Hugo post at <blog dir>/<slug>.md and, by default, opens a pull request on branch pulse/publish-<slug>. Nothing goes live until someone merges it.

No third-party social API is involved. The post goes to your own repository with your own GitHub token.

Settings

VariableDefaultMeaning
PULSE_APPLY_ENABLEDoffMust be exactly true.
PULSE_PUBLISH_BLOGfollows the globalSet false to silence only the blog.
PULSE_SITE_REPOnone, requiredowner/repo of your site.
PULSE_SITE_BRANCHmainBase branch.
PULSE_SITE_BLOG_DIRcontent/blogWhere posts go.
PULSE_SITE_PUBLISH_MODEprpr opens a pull request. commit pushes to the base branch and is live at once.
PULSE_SITE_AUTHORomittedThe author in the post’s front matter.
PULSE_SITE_BASE_URLomittedYour site’s base URL, used for the canonical link.

The GitHub token comes from the GitHub connection of the user who owns the content. See Connections.

When it refuses

MessageCause
website publishing is disabled: ...The blog channel is not armed. The message names the layer that decided.
no github integration/token configured for user ...The content’s owner has no GitHub connection.
PULSE_SITE_REPO is not set — refusing to publish; set it to YOUR site repo as owner/repoNo target repository.
invalid site repo "...": expected owner/repoThe repository is malformed.
refusing to publish empty contentThe post has no title or body.

The daily blog drafting only runs while the blog channel is armed. A disarmed channel costs no model time.

The daily site audit

Once a day, at 03:47 UTC, the site audit engine runs the relevance audit against one URL and stores the full report. It also files a readable digest as content on the site_audit channel. That channel is not publishable: the digest exists to be read.

VariableMeaning
PULSE_SITE_AUDIT_URLThe site to audit.
PULSE_SITE_BASE_URLUsed when PULSE_SITE_AUDIT_URL is unset.

With neither set, the engine does not start and logs Site Audit Engine: NOT started — no target site; set PULSE_SITE_AUDIT_URL (or PULSE_SITE_BASE_URL).

The first audit after a deploy waits for the next 03:47 UTC slot. Run one on demand from Site Audit at any time. Each audit is limited to 10 minutes. A run that scored nothing, for example because the site was unreachable, is recorded as a failure rather than a result.

The engine audits and records. It never fixes. Fixing stays a human decision.

Audit-fix pull requests

From a relevance audit report, a person can apply the fix artifacts to a site repository (ApplyAuditActions). See Apply the fixes.

  • plan is a dry run and always allowed.
  • apply, commit, and pr need PULSE_APPLY_ENABLED=true and a signed-in caller.
  • In pr mode with a GitHub connection, PULSE opens the pull request against the connection’s owner and repo, on branch seo/pulse-remediation by default, against main.
  • Copy and infrastructure changes are returned as manual and never applied.