Workflow and Pipeline Governance Framework
This is the single canonical reference for workflows and pipelines in this repo. Read this before creating, renaming, or removing any workflow.Outcome we are building
This repo is ownerless and self-governed. The product itself runs the rules: detects breaks, fixes what it can, raises issues for what it cannot, and documents every change without human babysitting. The framework below describes what that system must look like. Target end state:- Six action workflows. One per concern. Maintenance scales with the number of concerns, not the number of scripts.
- Workflows are thin dispatchers. YAML answers when, where, with what permissions. All business logic lives in governed scripts under
operations/scripts/. Inline JavaScript over 50 lines is a defect. - Local CLI equivalence on every dispatcher. Any contributor (human or AI agent) can run any pipeline locally with
--dry-run, with no CI trigger and no GitHub secrets, before pushing. - Prevention at the earliest layer (D-GOV-08). Every governance rule fires at the earliest possible layer. Detection at later layers is a fail-safe, never the primary mechanism. The five-layer chain – write time (PreToolUse hook), commit time (pre-commit), PR time (validator), post-merge (auto-repair), schedule (drift scan) – applies to every governed surface. A rule that only catches violations on schedule is a rule that lets violations land.
- Detect, repair, escalate, verify. Every detection routes to a response. No headless scans. No findings die in a log. Remediators support
--verifyso successful fixes survive and only regressed files revert. - Self-documenting. The actions library, script registry, and decisions registry regenerate from data on every change. No manual documentation sync.
- One taxonomy spine. 7 types times 7 concerns times 8 pipeline tags. Every workflow and every script declares all three. The system is searchable, mappable, and predictable.
- Bottom-up integrity. Every script has a verified purpose, a known caller, an SME endorsement, and a place in the taxonomy. Orphan scripts are archived, not preserved out of caution.
- Every folder is governed (D-GOV-08). No commit of files that do not belong. Every folder hosting repo-influencing files declares an explicit allowlist enforced through the five-layer prevention chain.
- Composable at every tier. Every script (atomic, pipeline, meta) is independently runnable via
nodewith--dry-run. A developer can call any pipeline directly without going through CI.
What the product needs to do
- Protect itself. Detect breaks. Auto-fix what it can. Raise issues for what it cannot. Block bad changes at PR time.
- Keep itself current. Pull fresh external data. Regenerate derived files. Detect drift.
- Maintain its own standards. Enforce voice, grammar, spelling, terminology, visual identity.
- Make itself findable. Regenerate AI and search surfaces on every change.
- Document itself. Catalogues, indexes, registries regenerate from data.
- Govern itself. Rules enforced, issues managed, drift self-healed.
Pipeline architecture (D-ACT-08)
The dispatcher model
Every workflow YAML is a dispatcher. Workflows handle trigger, environment, permissions, secrets, concurrency, and orchestration. They do not contain business logic. Typed work lives in scripts.| Layer | Owns | Has type? |
|---|---|---|
| Workflow YAML | When, where, permissions, concurrency, commit/push, issue creation, secrets injection | No (every workflow is a dispatcher) |
| Script | All business logic, file I/O, exit codes, dry-run, verify, structured output | Yes (7-type taxonomy) |
dispatch-{concern}.yml files are the concern dispatchers (the “actions” in this framework’s terminology – one per concern). The 5 interface-governance-*.yml files (assign-reviewers, close-linked-issues, index-issues, intake-discord-issues, label-issues) wrap interface type scripts that react to issue/PR/webhook events; they are tagged # pipeline: P7 distinct from the P2–P6 dispatcher taxonomy. Both classes live in .github/workflows/ for an active total of 11 workflows.
Four-tier composable dispatch architecture
The repo orchestrates work through four tiers. Every script at every tier is independently runnable vianode with --dry-run. A developer can call any pipeline, any meta-bundle, or any atomic directly without going through CI.
| Tier | What it is | Count (live 2026-05-25) | Composability |
|---|---|---|---|
| 1. Action | Thin workflow YAML files in .github/workflows/. Fires on event, calls a meta dispatcher (or pipeline directly). | 6 dispatch- actions + 5 interface-governance workflows = 11 active | Triggered by GitHub events only – not runnable locally. |
| 2. Meta dispatcher | Optional script that bundles related pipelines into a higher-level entry point (for example: “all health PR pipelines”). | ~20 (3 per concern average) | node dispatch-{concern}-{verb}.js --dry-run |
| 3. Pipeline dispatcher | Owns one full detect-repair-verify-escalate cycle for one niche. Accepts --mode pr|scheduled|manual. | ~80 (one per niche; tier 2 + tier 3 = 100 dispatch scripts total) | node dispatch-{niche}.js --mode pr --dry-run |
| 4. Atomic script | Single-purpose, type-pure (validator, audit, remediator, generator, integrator, or interface). | 230 wired | node {type}-{thing}.js --files {paths} |
- Action YAMLs:
dispatch-{concern}.yml. Concern from the 7-enum. - Meta dispatchers:
dispatch-{concern}-{verb}.js. Verb from the 11-enum and indicates which kind of pipelines are bundled (checkfor PR-time bundles,scanfor scheduled bundles,repairfor manual bundles,generatefor post-merge bundles,updatefor scheduled integrator bundles,react/intake/indexfor event handlers). - Pipeline dispatchers:
dispatch-{niche}.js. Verbdispatchbecause the pipeline orchestrates a full cycle (not a single verb’s work). Niche is the second-level grouping inside a concern (wcag,page-integrity,em-dashes,contract-addresses,folder-allowlist, etc.). - Atomic scripts: verb-noun where verb matches the script’s type (
check-*for validators,scan-*/audit-*for audits,repair-*for remediators,generate-*for generators,fetch-*/update-*for integrators). One concern per atomic.
dispatch to signal this is intentional orchestration.
Composability worked example:
(NEW – Phase 3) do not exist yet and will be created during implementation. A pipeline is not composable if any of its lifecycle atomics is missing – every pipeline shown here is targeted at full closure.
The implicit verify step: after a pipeline runs its repair atomics, it re-runs its detect atomics on the affected files. This is the same script invocation with --verify flag rather than a separate atomic. Only files that pass re-detection survive; regressed files revert.
The implicit escalate step: every pipeline includes lib/rolling-issue.js to open, update, or close a rolling GitHub issue per residual finding. Auto-fixable findings never reach escalation; only what cannot be repaired by the cycle gets human attention.
dispatch-health.yml (action)
dispatch-health-check.js (PR meta)
dispatch-health-scan.js (scheduled meta)
dispatch-health-repair.js (manual meta)
dispatch-brand.yml (action)
dispatch-copy.yml (action)
dispatch-discoverability.yml (action)
dispatch-maintenance.yml (action)
dispatch-governance.yml (action)
| Pipeline | New atomic | Type | Purpose |
|---|---|---|---|
| dispatch-page-structure | repair-anchor-usage.js | remediator | Pairs with check-anchor-usage |
| dispatch-page-structure | repair-description-quality.js | remediator | Pairs with check-description-quality |
| dispatch-page-structure | repair-lint-structure.js | remediator | Pairs with lint-structure |
| dispatch-page-rendering | check-broken-links.js, repair-broken-links.js | validator + remediator | Replace mintlify integration with first-party atomic |
| dispatch-content-quality | repair-content-quality.js | remediator | For deterministic content fixes |
| dispatch-openapi-reference | repair-openapi-reference.js | remediator | Regenerate from spec source, open PR |
| dispatch-banned-words | repair-banned-words.js | remediator | For replaceable terms |
| dispatch-ownerless-language | check-ownerless-language.js | validator | Currently only repair atomic exists |
| dispatch-social-feeds | validate-social-feed-schema.js | validator | Schema verification on fetched data |
| dispatch-changelogs | validate-changelog-schema.js | validator | Schema verification |
| dispatch-showcase | validate-showcase-schema.js | validator | Schema verification |
| dispatch-og-images | check-og-images.js | validator | Verify all v2 pages have OG image |
| dispatch-seo-metadata | audit-seo-metadata.js | audit | Detect missing/stale SEO metadata |
| dispatch-component-registry | repair-component-imports.js, repair-component-css.js, repair-naming-conventions.js, repair-component-pattern-compliance.js, repair-component-layout.js | remediators | Pairs with component validators |
| dispatch-sdk-clients | validate-sdk-schema.js | validator | Schema verification |
| dispatch-contract-shadow | compare-shadow-to-production.js | validator | Shadow-vs-production diff |
| dispatch-release-version | validate-release-version.js | validator | Schema/format check |
| dispatch-config-flags | validate-config-flags-schema.js | validator | Schema verification |
| dispatch-exchanges-data | validate-exchanges-schema.js | validator | Schema verification |
| dispatch-folder-allowlist | check-folder-allowlist.js, audit-folder-allowlist.js, repair-folder-allowlist.js | validator + audit + remediator | Full triplet per D-GOV-08 |
| dispatch-codex-compliance | repair-codex-task-contract.js | remediator | For deterministic contract fixes |
| dispatch-script-locations | repair-script-locations.js | remediator | Auto-move via git mv |
| dispatch-workspace-retention | repair-workspace-retention.js | remediator | Auto-archive drift |
| dispatch-action-docs | check-actions-library.js | validator | Verify catalog-index integrity |
| dispatch-script-registry | check-script-registry.js | validator | Verify registry coverage |
operations/scripts/dispatch/governance/ and are wired via .claude/settings.json. The CI dispatchers above never call them; they run in the local editor session before code reaches git.
What the PR sees with this architecture:
- PR touching
v2/*.mdxtriggers up to 6 action workflows (one per concern, filtered bypaths:) - Each workflow runs ONE job per relevant trigger, with sequential steps inside calling pipeline dispatchers
- Each job appears as ONE PR check named “Concern · PR Check” (for example, “Health · PR Check”)
- A failed step in any job fails the entire concern check with a clear log entry showing which pipeline dispatcher caught what
node operations/scripts/dispatch/{content|governance}/{concern}/dispatch-{niche}.js --dry-run.
Pipeline patterns
Every pipeline takes one of seven shapes.| Pattern | Shape | Example |
|---|---|---|
| A: Integrate | Fetch external data, diff check, commit | Social feed updates, contract address sync |
| B: Generate | Build from internal data, commit | docs-index.json, llms.txt, AI sitemap |
| C: Check | Validate on PR, report pass or fail | Broken links, content quality, governance |
| D: Scan, report, act | Scheduled monitoring with routed response | Data freshness, external link audit, content quality scan |
| E: Repair | Fix broken state, commit or open PR | EN-GB style homogenisation, governance repair |
| F: React | Issue or PR lifecycle events with no file changes | Label, assign reviewer, intake from Discord |
| G: Orchestrate | Dispatch children, aggregate results | Post-merge sync, catalog generation |
Generate/verify pairs
Every Pattern B generator must have a matching Pattern C verifier that runs with--check on PR. The verifier compares the committed file to what the generator would produce. Drift fails the PR.
Every Pattern E remediator must accept --verify. After applying fixes the script re-runs the matching validator on affected files and reverts only files that regressed. Successful fixes survive even when one file fails.
Detect, repair, escalate, verify (D-GOV-03)
No headless scans. Every detection routes to one of four responses:| Detection | Route | Authority |
|---|---|---|
| Auto-fixable | Apply fix silently in CI | Highest preference |
| Auto-fixable but high blast radius | Open auto-fix PR | Medium |
| External dependency or human decision needed | Open rolling issue | Lower |
| Schema or syntax breakage on PR | Block merge with clear error | Last resort |
operations/scripts/interfaces/governance/lib/rolling-issue.js.
Local CLI equivalence (D-GOV-07)
Every dispatcher has a matching local script that can run the same pipeline without a CI trigger. The workflow is the CI orchestrator; the script is the portable logic. Three requirements:- Every script accepts
--dry-run(preview without writing) - Secrets-dependent scripts degrade gracefully when secrets are absent
- The actions-library page documents the local invocation command
Prevention at the earliest layer (D-GOV-08)
Every governance rule fires at the earliest possible layer. Detection at later layers is a fail-safe, not the primary mechanism. A rule that only catches violations on schedule is a rule that lets violations land. The five enforcement layers, from earliest to latest:| Layer | Trigger | Owner | What it does |
|---|---|---|---|
| 1. Write time | Claude PreToolUse hook | pre-tool-guard.js and siblings in operations/scripts/dispatch/governance/ | Blocks Edit/Write before the file lands. Allowlist, render gate, em-dash sanitiser, frontmatter sanitiser. |
| 2. Commit time | .githooks/pre-commit | Pre-commit hook | Rejects unauthorised paths and structural violations in the staged diff. Works for contributors not running Claude Code. |
| 3. PR time | dispatch-{concern}.yml PR job → dispatch-{concern}-check.js meta | PR validator pipelines | Server-side check on every PR. Fails the check on violations. Posts advisory comment for soft gates. |
| 4. Post-merge | dispatch-{concern}.yml post-merge job → dispatch-{concern}-sync.js or dispatch-{concern}-generate.js meta | Post-merge remediators and generators | If something landed despite layers 1-3 (direct push, hook bypassed), auto-archive or auto-fix on merge. |
| 5. Schedule | dispatch-{concern}.yml scheduled job → dispatch-{concern}-scan.js meta | Scheduled audit pipelines | Last-resort drift scan with rolling issue. Fail-safe only – anything caught here represents an upstream gate that failed. |
Every folder is governed (D-GOV-08)
No commit of files that do not belong. Every folder hosting repo-influencing files declares an explicit allowlist enforced through the five-layer prevention chain above. Allowlist rules:- Explicit, closed list (exact paths or globs)
- Stored at
{folder}/.allowlistfor portability - One entry per line, documented purpose per entry
- Registered in
operations/governance/config/repo-governance-surfaces.json(D-ACT-10)
dispatch-folder-allowlist.js --mode pr (layer 3), --mode post-merge (layer 4), --mode scheduled (layer 5), plus the pre-tool-guard.js extension for layer 1 and the pre-commit gate for layer 2. The allowlist files themselves are governed by the same chain – they are the source of truth, not generated.
Taxonomy
7 types (D-ACT-01, D-ACT-07)
| Type | Purpose |
|---|---|
integrator | Pulls external data into the repo |
generator | Produces files from internal repo data |
validator | Enforces rules with pass/fail gate on PR |
audit | Read-only scheduled monitoring and reporting |
remediator | Auto-fixes broken state with optional commit |
dispatch | Orchestrates multiple scripts or workflows |
interface | Reacts to issue, PR, or external events |
7 concerns (D-ACT-05)
| Concern | What it covers |
|---|---|
copy | Written text, data standards, spelling, grammar |
health | Site integrity, links, rendering, freshness, assets |
maintenance | Indexes, catalogues, registries, changelogs |
discoverability | SEO, AEO, AI indexing, translation |
governance | System rules, compliance, issue and PR management |
brand | Style, formatting, page structure, voice |
integrations | External data feeds and APIs |
8 pipeline tags (D-ACT-02)
| Tag | Trigger | Authority |
|---|---|---|
| P2 | PR (required check) | Blocks merge |
| P3 | PR (advisory) | Reports only |
| P4 | Push to deploy branch | Auto-commit |
| P5 | Schedule (read-only) | Advisory, rolling issue |
| P5-auto | Schedule plus auto-commit | Writes to repo |
| P6 | Schedule plus auto-fix | Self-heal, may open PR |
| manual | workflow_dispatch only | Human-triggered |
| event-driven | repository_dispatch or issues | Reactive |
Naming convention (D-ACT-04)
Pattern:type-concern-verb-name.yml
Example: integrator-maintenance-update-contract-addresses.yml
The verb is one of a closed enum of 11: update, generate, check, scan, repair, dispatch, label, index, intake, close, assign.
The name segment describes what the workflow does, not how it is implemented. If someone unfamiliar with the repo cannot guess the purpose from the filename, the name is bad.
In the four-tier architecture, action workflows use dispatch-{concern}.yml (verb is dispatch, name is the concern). Pre-existing single-script workflows that have not yet been consolidated may still use type-prefixed names (e.g. integrator-maintenance-update-contract-addresses.yml) until they fold into their concern’s action.
Required standards
Every active workflow meets these. Violations block the PR viavalidator-governance-check-workflow-governance.yml.
| Standard | Source | Enforcement |
|---|---|---|
Filename follows type-concern-verb-name.yml | D-ACT-04 | check-workflow-governance |
Governance comment headers (# type:, # concern:, # pipeline:) | D-ACT-08 | check-workflow-governance |
Listed in actions-audit.json | D-ACT-08 | check-workflow-governance |
Has matching docs page in .github/workspace/actions-library/ | D-ACT-08 | check-workflow-governance |
Generator workflows declare concurrency: block | D-ACT-03 | check-workflow-governance |
Auto-commit workflows declare concurrency: | D-ACT-03 | check-workflow-governance |
All called scripts live under operations/scripts/ with 11-tag JSDoc | D-ACT-06, script framework | check-jsdoc-headers |
Output locations follow D-ACT-09 (reports in workspace/reports/{concern}/, data in snippets/data/{domain}/) | D-ACT-09 | manual review at audit |
| Workflows are pure dispatchers; inline scripts under 50 lines | D-ACT-08 | manual review |
| Local CLI equivalent documented in actions-library | D-GOV-07 | manual review |
Required labels read from .github/config/labels.json | D-GOV-04 | manual review |
Self-documenting pipeline
The actions library at.github/workspace/actions-library/ regenerates from actions-audit.json whenever workflows change. No manual sync.
actions-audit.json registry is the source of truth. Documentation is derived. Editing the .mdx pages directly is wrong.
Locked decisions
18 decisions constrain the framework. Read the full text in.github/workspace/decisions-log.mdx and .github/workspace/design/governance/design-overview.md.
| ID | Topic | Effect |
|---|---|---|
| D-ACT-01 | interface is the 7th type | Event-reactive workflows are not pipeline-shaped |
| D-ACT-02 | P5-auto distinct from P5 | Read-write vs read-only have different error handling |
| D-ACT-03 | Data-feed consolidation pattern | Many similar feeds collapse into one matrix dispatcher |
| D-ACT-04 | Naming convention | type-concern-verb-name.yml with closed verb enum |
| D-ACT-05 | 7 concerns | Replaces earlier 4-concern model |
| D-ACT-06 | Scripts live in operations/scripts/ | No business logic in .github/scripts/ |
| D-ACT-07 | automation renamed integrator | Names what it does, not what it is |
| D-ACT-08 | Workflows are dispatchers | Type reflects the script |
| D-ACT-09 | Output location conventions | Reports, data, indexes, config each have a fixed home |
| D-ACT-10 | Unified governance registry | operations/governance/config/repo-governance-surfaces.json is canonical |
| D-GOV-01 | Governance is enforcement infrastructure | Concerns own rules; governance owns pipelines |
| D-GOV-02 | Categories are enforcement layers | Pre-commit, PR, post-merge, scheduled, self-heal, hooks, issue lifecycle |
| D-GOV-03 | Every detection self-repairs or escalates | No headless scans |
| D-GOV-04 | Tooling makes correct the default | Templates, scaffolds, labels |
| D-GOV-05 | Advisory before hard gate | New enforcement starts at P3 |
| D-GOV-06 | Script framework aligned to actions framework | 7 types, 7 concerns |
| D-GOV-07 | Workflow dispatchers have local CLI equivalents | Testable without CI |
| D-GOV-08 | Every folder is governed; prevention at earliest layer | Five-layer chain, no commit of files that do not belong |
What this framework supersedes
| Doc | Status | Authority |
|---|---|---|
.github/workspace/design/governance/consolidated-architecture.md | Superseded | Historical 47-workflow target. Current target is 6 actions + composable dispatcher tiers. Kept for design history. |
.github/workspace/framework-canonical.md | Working spec | Deeper internal detail. Synced from this published doc. |
.github/workspace/outcomes.md | Reference only | Visual maps and Mermaid diagrams. Snapshot in time. |
/Users/alisonhaire/.claude/plans/soft-gliding-falcon.md for the active session. When the plan completes, its outcomes fold into this framework and the plan is archived.
Canonical sources
| Source | Role |
|---|---|
| This page | Published canonical framework. Read before any workflow change. |
.github/workspace/decisions-log.mdx | Locked decisions (D-ACT-01..10, D-GOV-01..08). Edit only via new decision that explicitly supersedes. |
.github/workspace/framework-canonical.md | Internal working spec. Deeper pattern detail. |
.github/workspace/actions-library/actions-audit.json | Workflow registry. Source for auto-generated docs. |
.github/workspace/actions-library/ | Auto-generated per-workflow documentation. Read, do not edit. |
docs-guide/frameworks/script-framework.mdx | Companion framework for scripts under operations/scripts/ |
docs-guide/policies/governance-index.mdx | Index of all governed surfaces. Entry point. |
operations/governance/config/repo-governance-surfaces.json | Unified governance registry. Single source for governed surfaces. |
How to use this framework
Before creating a workflow:- Confirm the work cannot be done by an existing dispatcher (consolidate first – there are only 6 actions, one per concern)
- Identify the concern, the niche, and the trigger pattern
- Add or extend a pipeline dispatcher (
dispatch-{niche}.js) under the right concern folder - Add the atomic scripts as needed under the matching type folders, each with 11-tag JSDoc
- Add
--dry-runand--verifyto every script per D-GOV-07 - Register the workflow in
actions-audit.json - Open a PR.
validator-governance-check-workflow-governance.ymlconfirms compliance.
- Check who references it (
grep -rE workflow-nameacross yml, js, json, mdx) - Update every reference in the same PR
- Archive the old file under
.github/workflows/x-archive/(D2 no-deletions policy) - Update
actions-audit.jsonand re-run the action docs generator