fork-sync-all

Sync · Mirror · Automate

fork-sync-all is the control plane for the Interested-Deving-1896 GitHub org. It mirrors repositories into OpenOS-Project-OSP (GitHub) and then to openos-project (GitLab), manages READMEs across ~49 OSP-bound repos, syncs upstream forks, and runs org-wide maintenance workflows.

180 Workflows GitHub Pages Built with Ona

Quick navigation

Architecture

Three-org mirror chain, data flow, GitLab subgroup map, token model, quota layers.

Workflow Triggers

All 180 workflows — schedules, triggers, cross-workflow dependencies, index + glossary.

Operations

GitHub Actions limits, quota management, concurrency groups, schedule summary.

Quota Costs

Per-workflow REST call cost table, daily budget, REST→GraphQL savings.

Runbooks

Quota exhaustion, queue pile-up, token expiry, mirror chain broken, incident response.

Contributing

Adding workflows, scripts, config files; testing; white-labeling guide.

Source Tree

Full directory/file index of the entire fork-sync-all source hierarchy.

Glossary

Definitions for every term, acronym, and concept used across the project.

fork-sync-all

Built with Ona Open Collective

When Git Platforms Give You Anxiety Attacks, Who Are You Going To Call? Fork-Sync-All!

Control plane for the Interested-Deving-1896 GitHub org. Runs 147 GitHub Actions workflows that keep three GitHub orgs and two GitLab groups in sync, manage READMEs and badges across OSP-bound repos, resolve CI failures, and maintain registered upstream imports.

Workflows180
Registered imports157
Template consumers82
GitLab subgroups14
GitLab repos mirrored225

How it works

┌─────────────────────────────────────────────────────────────────────────────┐
│  Mirror chain (outward, every 6h)                                           │
│                                                                             │
│  Interested-Deving-1896 ──► OpenOS-Project-OSP                              │
│          ▲                         │                                        │
│          │                         ▼                                        │
│          │              OpenOS-Project-Ecosystem-OOC                        │
│          │                         │                                        │
│          │                         ▼                                        │
│          │                  GitLab openos-project                           │
│          │             (14 subgroups, 225 repos mirrored)                   │
│          │                                                                  │
│          └──── upstream-commits / upstream-prs (OSP + OOC → I-D-1896) ─────┘
└─────────────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────────────┐
│  Full pipeline (manual / monthly)                                           │
│                                                                             │
│  flush-lifecycle ──► pre-flush-prep ──► full-chain-flush (25 stages) ──► post-flush-prep │
│       │                      │                             │                │
│  QUOTA_SNAPSHOT          QUOTA_SNAPSHOT               QUOTA_SNAPSHOT        │
│  (chain entry)           (chain start)                (chain exit)          │
└─────────────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────────────┐
│  Quota & queue management (automatic, every 30 min)                         │
│                                                                             │
│  quota-reserve ──► queue-manager ──► rate-limit-rerun                       │
│                                           │                                 │
│                                    cancel-stale-runs                        │
│                                      quota-monitor                          │
└─────────────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────────────┐
│  OTA system (versioned updates for independent forks)                       │
│                                                                             │
│  ota-release ──► ota-deliver ──► opted-in forks (PR per fork)               │
│       ▲                                                                     │
│  semver tag push                                                            │
│                                                                             │
│  ota-reconcile (weekly) ──► path A: stamp · B: drift PR · C: quota PR      │
└─────────────────────────────────────────────────────────────────────────────┘

This project provides automated management for git repositories and organizations across multiple git-based platforms. It addresses challenges such as keeping forks synchronized, generating READMEs, injecting badges, tracking upstream changes, mirroring repositories, and managing releases. It is used by developers and organizations to streamline repository maintenance and ensure consistency across distributed version control systems.


Documentation

ResourceDescription
Full documentationArchitecture, quota management, workflow reference, runbooks
Workflow TriggersAll 185 workflows — schedules, triggers, synopses (plain text · published)
OTA ReconcileHybrid A/B/C fallback layer for mirror-chain consumers
OTA SystemOTA delivery architecture and opt-in guide
AI Agent CostsOCU pricing, tokenizer reference, per-task estimates
Quota CostsPer-workflow REST call estimates (p50/p95)
Workflow SchedulingOptimal dispatch windows, quota floors, EST/UTC timing
RunbooksIncident response and operational procedures

Workflow groups

158 workflows across 20 functional groups. Full detail in DOCS/workflow-triggers.md.

GroupWorkflowsDescription
Accessibility1CODEOWNERS coverage, screen-reader scan, WCAG audit, audio overview, Braille output
AI & Cost Tracking4Session cost log, weekly price sync
BDFS / Filesystem Workspace5DwarFS/BTRFS workspace dev and packaging
Bugzilla Integration1Sync commits/PRs to Bugzilla, milestone shipping
Build & Release10Build, checks, release, kernel content, arch config
CI & Failure Resolution7Rate-limit rerun, failure resolver, runner status
Documentation & Publishing9mdBook, GitBook, NotebookLM, translate docs, triggers doc
Fork & Import Sync20Upstream fork sync, registered imports, platform import
Full Pipeline8pre-flush → full-chain-flush → post-flush + critical-deploy
Git Platform Sync5Bidirectional push/pull sync with GitLab
Infrastructure & Environment4Dev container SDK, Incus, FSA API
Maintenance & Housekeeping16Config validation, cleanup, token rotation, dep updates
Mirror Chain14Outward mirror: I-D-1896 → OSP → OOC → GitLab
OSP-Bound Repo Management7Add mirror repo, CI status, setup OSP mirrors
OTA System5Release delivery, reconcile, self-update, discover, opt-in
PR Governance & Trust10Vouch, PR gate, labeler, auto-merge, rebase
Quota & Queue Management5Reserve, dedup, monitor, cost registry
README Management10Create, update, badge, translate, validate READMEs
Security & Compliance6SBOM, CodeQL, vendor audit, arch audit, pin workflows
Utility / On-Demand11Manual and specialised workflows

Key config files

FilePurpose
config/agent-cost-profiles.ymlMachine-readable AI agent cost profiles (8 variants, 10 complexity tiers)
config/gitlab-subgroups.ymlSingle source of truth for GitLab subgroup placement
config/ota-blocklist.ymlOrgs/profiles excluded from OTA delivery by default
config/ota-registry.ymlOpted-in forks receiving OTA updates
config/template-consumers.yml80 repos that receive template updates via sync-template.yml
config/template-manifest.ymlProfile definitions for template sync (full / mirror / infra-core / standalone)
config/workflow-priority-tiers.ymlCancellation priority (Tier 1 = never cancel, Tier 4 = cancel first)
config/workflow-quota-costs.ymlPer-workflow REST call cost estimates — drives quota pre-flight and quota-reserve.yml
config/workflow-sync.ymlWhich workflows have GitLab CI counterparts
registered-imports.json156 upstream repos kept in ongoing sync

Secrets

SecretUsed byNotes
ACTIVITYSMITH_API_KEYfull-chain-flush.ymlOptional — live activity tracking; skipped if unset
ADD_MIRROR_REPO_SYNCadd-mirror-repo.ymlScoped PAT for repo creation
BITBUCKET_TOKENimport-repo.yml, sync-registered-imports.ymlBitbucket app password (private repos only)
GH_SYNC_TOKENGitLab CI sync-from-gitlab jobSame PAT stored as a GitLab CI variable
GITEA_TOKENimport-repo.yml, sync-registered-imports.ymlGitea/Codeberg PAT (private repos only)
GITLAB_SYNC_TOKENmirror-osp-to-gitlab.yml, post-flush verificationGitLab PAT for mirror operations
GITLAB_TOKENGitLab workflowsGitLab PAT — api + write_repository on openos-project
NOTEBOOKLM_AUTH_JSONgenerate-notebooklm.ymlShort-lived auth state, rotated weekly by refresh-notebooklm-auth.yml
OSP_ADMIN_TOKENOSP org admin operationsPAT with admin:org on OpenOS-Project-OSP
SOURCEHUT_TOKENimport-repo.ymlSourcehut PAT (private repos only)
SYNC_IN_SERVER_URLsync-in.ymlURL of the local sync-in server instance
SYNC_TOKENAll workflowsGitHub PAT — repo + workflow + admin:org scopes
gh secret set <SECRET_NAME> --repo Interested-Deving-1896/fork-sync-all

Rate limits

Both SYNC_TOKEN and GH_SYNC_TOKEN belong to the same user and share the same 5,000 req/hr REST bucket. Treat them as one pool. raw.githubusercontent.com fetches do not count against the quota.

APILimitReset
GitHub REST5,000 req/hr per tokenTop of the hour
GitHub GraphQL5,000 pts/hr (counts as 1 REST call)Top of the hour
GitHub ModelsVaries by modelPer-minute window
GitLab REST2,000 req/min per tokenPer-minute window

quota-reserve.yml cancels low-priority queued runs when remaining quota drops below 1,000. Check current quota:

curl -sf -H "Authorization: token $SYNC_TOKEN" \
  "https://api.github.com/rate_limit" | \
  python3 -c "
import sys, json, datetime
d = json.load(sys.stdin)['resources']['core']
reset = datetime.datetime.utcfromtimestamp(d['reset']).strftime('%H:%M UTC')
print(f'remaining={d[\"remaining\"]}  resets={reset}')
"

GitLab subgroups

14 subgroups under gitlab.com/openos-project, 225 repos mirrored. Assignments are in config/gitlab-subgroups.yml.

SubgroupReposFocus
accessibility_deving9Screen readers, Braille, WCAG auditing, audio overviews
agnostic-api_deving29Unified Agnostic API — virtual filesystems, AI/LLM adapters, OS-compat layers
ai-agents_deving10AI agent frameworks and tools
cachyos_deving12CachyOS distro packages
git-management_deving9Git tooling and org management
immutable-filesystem_deving1Immutable filesystem projects
incus_deving49Incus container/VM tooling
linux-kernel_filesystem_deving14Kernel and filesystem repos
neon-deving8KDE Neon repos
ops30Infrastructure and org management tooling
penguins-eggs_deving17penguins-eggs distro tools
rust-systems_deving2Rust systems programming
taubyte_deving1Taubyte protocol
yaml-tooling_deving34YAML tools, linters, schema validators, GH Actions tooling

All automation is implemented as Bash scripts in scripts/ and GitHub Actions workflows in .github/workflows/. There are no compiled artifacts, no Node.js runtime dependencies, and no build step — every workflow runs directly against the shell scripts.

.
├── .github/workflows/    # 147 GitHub Actions workflows
├── scripts/              # Bash automation scripts
│   └── includes/         # Shared helpers (gh-api.sh, budget.sh, quota-instrument.sh, …)
├── config/               # YAML config: subgroup maps, quota costs, priority tiers, …
├── DOCS/                 # mdBook source (architecture, runbooks, quota reference, …)
│   └── generated/        # Auto-generated pages (workflow reference, source tree, …)
├── services/             # Long-running service helpers (sync-in server)
├── vendor/               # Third-party components hosted by fork-sync-all
├── .devcontainer/        # Dev container definition and local features
├── .ona/                 # Ona automations (services + tasks)
├── registered-imports.json  # Upstream repos kept in sync
├── book.toml             # mdBook configuration
└── Dockerfile            # Container image for CI runners

Scripts communicate via environment variables and exit codes. Shared helpers in scripts/includes/ provide GitHub API access (gh-api.sh), quota budgeting (budget.sh), and run instrumentation (quota-instrument.sh). See Architecture for the full data-flow diagram.


The repository uses GitHub Actions for continuous integration and automation. Below are the workflows and their purposes:

  • build.yml: Builds the project for all supported platforms. No secrets required.
  • test.yml: Runs unit and integration tests. No secrets required.
  • lint.yml: Checks code formatting and style using ESLint. No secrets required.
  • sync-forks.yml: Synchronizes forks with upstream repositories. Requires UPSTREAM_TOKEN secret.
  • mirror-orgs-full.yml: Mirrors repositories across organizations. Requires MIRROR_TOKEN secret.
  • inject-badges.yml: Injects badges into README files. No secrets required.
  • release.yml: Manages release creation and tagging. Requires RELEASE_TOKEN secret.
  • check-ci.yml: Validates CI configuration files. No secrets required.
  • cleanup-branches.yml: Deletes stale branches. Requires GITHUB_TOKEN secret.
  • codeql-analysis.yml: Performs CodeQL security analysis. Requires GH_CODEQL_TOKEN secret.

Secrets must be configured in the repository settings under "Settings > Secrets and variables > Actions."


Origins

Auto-generated by generate-dep-graph.sh. Do not edit manually. Last generated: 2026-06-12 (stub — full graph generated on next scheduled run)

This graph maps every OSP-bound repo in Interested-Deving-1896 to its upstream origin(s), as declared in each repo's ## Origins README section.

RepoOriginHostFork in I-D-1896
github-codeownerskohofinancial/github-codeownersGitHub
github-codeownersjjmschofield/github-codeownersGitHub
gitlab-enhancedopenos-project/git-management_deving/gitlab-enhancedGitLab

Summary

  • OSP-bound repos scanned: stub (full scan runs weekly via generate-dep-graph.yml)
  • Tooling dependencies tracked: github-codeowners (CODEOWNERS auditing across all OSP repos)

Tooling Dependencies

ToolPurposeUpstream
github-codeownersAudits CODEOWNERS coverage — surfaces ownership stats per repokohofinancial/github-codeowners

Resources

FileDescription
registered-imports.jsonRegistered ongoing-sync imports
dep-graph/origins.mdDependency graph (Markdown table)
.gitlab/merge_request_templates/Default.mdGitLab MR template
config/gitlab-subgroups.ymlGitLab subgroup map

Accessibility

This repo uses automated accessibility auditing via check-accessibility.yml.

Checks include: CODEOWNERS ownership coverage, README screen-reader compatibility, WCAG 2.1 AA HTML compliance, audio overview (espeak-ng), and Braille output (liblouis).

Run the Check Accessibility workflow to generate the first report and accessibility artifacts. See DOCS/accessibility.md for the full reference.


This repo is maintained in Interested-Deving-1896/fork-sync-all and mirrored through:

Interested-Deving-1896/fork-sync-all  ──►  OpenOS-Project-OSP/fork-sync-all  ──►  OpenOS-Project-Ecosystem-OOC/fork-sync-all

Changes flow downstream automatically via the hourly mirror chain in fork-sync-all. Direct commits to OSP or OOC are detected and opened as PRs back to Interested-Deving-1896.


Contributors

@Interested-Deving-1896: 480 commits
@github-actions[bot]: 78 commits
@actions-user: 7 commits
@dependabot[bot]: 6 commits
@web-flow: 5 commits

Note: This repository may be a mirror. Please refer to the upstream source for additional context.


License

AGENTS.md

Conventions, patterns, and known pitfalls for AI agents working in this repo.


Repository overview

fork-sync-all is the control plane for the Interested-Deving-1896 GitHub org. It mirrors repos into OpenOS-Project-OSP (GitHub) and then to openos-project (GitLab), manages READMEs across ~49 OSP-bound repos, syncs upstream forks, and runs org-wide maintenance workflows.

Key config files:

  • config/gitlab-subgroups.yml — single source of truth for GitLab subgroup placement
  • registered-imports.json — upstream repos to keep in sync
  • scripts/ — all automation scripts
  • .github/workflows/ — GitHub Actions workflows

Key directories:

  • vendor/ — third-party components hosted/deployed by fork-sync-all (e.g. infra-dashboard). Everything in scripts/ is first-party automation. Do not move scripts into vendor/.

GitHub API quota

Both GH_TOKEN and SYNC_TOKEN belong to the same user (ID 202036334) and share the same 5000 req/hr REST bucket. Treat them as one pool.

  • raw.githubusercontent.com fetches do not count against the quota
  • GraphQL counts as 1 call regardless of how many repos are queried
  • The quota pre-flight in workflows uses MIN_QUOTA (typically 1000–1500) to skip runs when the bucket is too low; quota-monitor.sh retries after reset

When quota is at 0, avoid any gh api, curl .../api.github.com/..., or gh_get calls. Check reset time with:

curl -sf -H "Authorization: token $SYNC_TOKEN" \
  "https://api.github.com/rate_limit" | jq '{remaining, reset: (.resources.core.reset | todate)}'

AI agent cost budgeting

This repo uses multiple AI agents. Each has a different billing model — understand which resource you're spending before starting a task.

AgentBillingApprox. cost per session
Ona Agent (Claude 4 Sonnet)OCUs ($0.25/OCU)1–31 OCUs ($0.25–$7.75) depending on task size
Codex (Ona-managed)OCUs (env + model)Same as Ona Agent
Codex (ChatGPT plan connected)OCUs (env only) + OpenAI~1 OCU/hr env; model via ChatGPT plan
GitHub Models (llm.sh)GitHub Models quota~0.25–1 OCU env runtime; model is free
Anthropic API directAnthropic pay-per-token~$0.30–$0.60/session; no OCUs

OCU top-up packages (one-time, $0.25/OCU flat): 40 OCUs/$10 · 100/$25 · 200/$50 · 400/$100 · 1,000/$250 · 2,000/$500 · 4,000/$1,000 · 8,000/$2,000

Rough task sizing (Ona Agent on Standard environment):

  • Small fix / single file: 1–4 OCUs
  • Multi-file feature + tests: 8–12 OCUs
  • Large session (3–4 hr, many files): 15–24 OCUs
  • Full end-to-end update: 19–31 OCUs

GitHub API quota and OCUs are independent. GitHub quota exhaustion pauses the agent but does not consume OCUs. OCU exhaustion stops the session regardless of GitHub quota state.

Full reference: DOCS/ai-agent-costs.md Machine-readable profiles: config/agent-cost-profiles.yml Log a session: gh workflow run track-agent-costs.yml --field agent=ona --field ...


Script conventions

All logging helpers must write to stderr

Every script defines some combination of info(), warn(), dry(), and log(). All must use >&2:

info() { echo "[script-name] $*" >&2; }
warn() { echo "[warn] $*" >&2; }
dry()  { echo "[dry-run] $*" >&2; }
log()  { echo "[$(date -u '+%H:%M:%S')] $*" >&2; }

Why this matters: Several functions are called inside $(...) subshell captures where their stdout becomes the captured value (e.g. README content, repo lists, API responses). Any logging call without >&2 inside such a function will corrupt the captured data.

This applies to includes/gh-api.sh too — merge_upstream() status messages must go to stderr since callers may capture its output via result=$(merge_upstream ...).

Known functions called inside $(...) captures — never emit to stdout inside these:

  • rewrite_readme() in update-readmes.sh
  • fill_missing_sections() in update-readmes.sh
  • build_readme() in create-readmes.sh
  • generate_*() functions in update-readmes.sh
  • merge_upstream() in scripts/includes/gh-api.sh

YAML parsing

Always use yaml.safe_load — never hand-rolled regex/indent parsers:

import yaml
with open(config_path) as f:
    config = yaml.safe_load(f)
subgroups = config.get("subgroups", {}) or {}

This applies to gitlab-subgroups.yml parsing in all scripts.

includes/ scripts

scripts/includes/budget.sh, scripts/includes/gh-api.sh, and scripts/includes/quota-instrument.sh are sourced by many scripts and workflows. Changes there have broad impact.

  • budget.sh — provides budget_init, budget_check, budget_report, osp_priority_repos, and workflow_min_quota. The latter reads per-workflow min_quota from config/workflow-quota-costs.yml.
  • gh-api.sh — provides gh_api, gh_get, gh_api_graphql, merge_upstream, get_default_sha. All status messages use >&2. Guard against double-sourcing is in place (_GH_API_LOADED). gh_get URL is a convenience GET wrapper around gh_api with full retry and reset-aware backoff — the canonical implementation that individual scripts should migrate to (see consolidation note below).
  • platform-adapter.sh — uniform interface for GitHub, GitLab, Gitea, Forgejo, and Codeberg. See Platform adapter below.
  • fsa-node-identity.sh — extends fsa-mode.sh with a chain position layer. See Node identity below.
  • auto-merge-prs.sh — standalone script (not an include); see Auto-merge PRs below.

gh_get / gh_api consolidation (complete)

All scripts now source includes/gh-api.sh for gh_get. The three tiers that existed during migration have been fully consolidated:

TierScriptsStatus
Full retry (canonical)check-osp-ci.sh, cleanup-branches.sh✅ migrated
No retry, fail-fastcreate-readmes.sh, inject-badges.sh, pre-flush-prep.sh, readme-wizard.sh, rebase-prs.sh, sync-template.sh, update-readmes.sh✅ migrated
No retry, silent failrerun-after-rate-limit.sh, scan-rate-limit-failures.sh✅ migrated (added || echo '{}' fallbacks on capture sites)

All new scripts should source includes/gh-api.sh and use gh_get directly. Do not define a local gh_get() in any new script.

  • quota-instrument.sh — provides qi_begin / qi_end for measuring REST quota consumption per workflow run. Wire into the main job step of any workflow you want to instrument. Writes a structured HTML comment to GITHUB_STEP_SUMMARY that update-quota-costs.yml parses weekly to compute observed p50/p95 values.

    qi_begin/qi_end must be in the same run: step_QI_BEFORE is a shell variable that does not survive across step boundaries. When the work spans multiple steps (e.g. delete-stale-repos.yml), persist the value via a temp file:

    # Step A — sample before
    source scripts/includes/quota-instrument.sh
    qi_begin
    echo "$_QI_BEFORE" > /tmp/qi_before
    
    # Step B (always()) — emit delta
    source scripts/includes/quota-instrument.sh
    if [[ -f /tmp/qi_before ]]; then
      _QI_BEFORE=$(cat /tmp/qi_before)
      qi_end
    fi
    

    If Step A is skipped (e.g. quota pre-flight exits early), /tmp/qi_before will not exist and the qi_end block silently no-ops — no spurious delta is recorded.

REST → GraphQL conversion

Prefer GraphQL over paginated REST for any loop that fetches the same data for multiple repos. GraphQL counts as 1 REST call regardless of how many repos are queried.

Standard pattern for org repo lists:

result=$(curl -sf \
  -H "Authorization: token ${GH_TOKEN}" \
  -H "Content-Type: application/json" \
  "${GH_API}/graphql" \
  -d "{\"query\":\"{ organization(login: \\\"${ORG}\\\") { repositories(first: 100) { nodes { name } pageInfo { hasNextPage endCursor } } } }\"}" \
  2>/dev/null || echo "{}")
echo "$result" | python3 -c "
import json,sys
d=json.load(sys.stdin)
for n in d.get('data',{}).get('organization',{}).get('repositories',{}).get('nodes',[]):
    print(n['name'])
" 2>/dev/null

Prefetch pattern for per-repo metadata (existence, pushedAt, README): Batch all repos into a single GraphQL call using aliases, populate an associative array, then read from the cache in the loop — zero REST calls per repo:

declare -A _REPO_EXISTS=()
# ... build aliases, fire one GraphQL call, populate _REPO_EXISTS ...
# In the loop:
[[ -z "${_REPO_EXISTS[$repo]:-}" ]] && continue  # skip non-existent repos

See sync-registered-imports.sh (prefetch_repo_metadata), mirror-releases.sh (prefetch_upstream_existence), and inject-badges.sh (list_gh_repos + _README_CACHE) for reference implementations.

What cannot be converted to GraphQL:

  • check-runs and statuses endpoints — not exposed in GraphQL
  • actions/workflows and actions/secrets — not in GraphQL
  • Write operations (create repo, push file, cancel run) — REST only

Tree fetches

Use ?recursive=1 on the git trees endpoint to get all file paths in one call, then check membership with grep -qxF before fetching individual files:

tree_json=$(gh_get "${GH_API}/repos/${owner}/${repo}/git/trees/HEAD?recursive=1")
tree_paths=$(echo "$tree_json" | jq -r '.tree[] | select(.type=="blob") | .path')
echo "$tree_paths" | grep -qxF "package.json" && # file exists, fetch it

Never probe file existence with per-file /contents/ calls in a loop.

YAML-safe shell in run: blocks

GitHub Actions run: blocks are YAML block scalars. The YAML parser processes the file before the shell runner sees it, so certain shell constructs break parsing even though they would be valid bash.

Patterns that break YAML — never use these inside run: blocks:

PatternWhy it breaksFix
VAR=" with newline before closing "Opens an unclosed YAML flow scalarUse printf or write to a temp file
python3 -c " with newline before closing "Same — unclosed flow scalarCollapse to a single-line -c invocation
--- on its own lineYAML document separatorUse ---- or printf '\xe2\x80\x94' for em dash
Heredoc end-marker that is a bare YAML keyword (YAML, EOF, END) at column 0Parsed as a bare mapping keyRename to OTA_CONFIG_EOF, PYEOF, etc. — anything not a YAML keyword
Multi-line git commit -m "..."Unclosed flow scalarUse $'subject\n\nbody' ANSI-C quoting or chained -m flags

Safe alternatives:

# Multi-line python: collapse to one line
repos=$(python3 -c "import yaml; d=yaml.safe_load(open('config/x.yml')); print(' '.join(d.get('repos',[])))")

# Multi-line variable: use printf into a temp file
printf 'line1\nline2\n' > /tmp/body.txt

# Multi-line commit message: ANSI-C quoting
git commit -m $'subject\n\nbody line 1\nbody line 2'

# Or chained -m flags (each becomes a paragraph)
git commit -m "subject" -m "body paragraph"

# Heredoc end-marker: use a non-YAML-keyword name
cat > file.yml << 'CONFIG_EOF'
...
CONFIG_EOF

The validator catches these: python3 scripts/validate-workflow-guards.py runs a YAML parse check across all 75 workflow files. Run it after editing any workflow. The full-suite parse check is also embedded in validate-config.yml.


Workflow patterns

Queue and quota management

Four workflows protect the system from quota exhaustion cascades and runner starvation:

WorkflowSchedulePurpose
queue-manager.ymlEvery 30 min + after rate-limit-rerunDeduplicates queued runs (keeps newest per workflow) and evicts runs queued > 25 min
quota-reserve.ymlEvery 30 min + after rate-limit-rerunCancels low-priority queued runs when quota drops below 1000. Uses per-workflow min_quota from config/workflow-quota-costs.yml for cost-aware cancellation.
critical-deploy.ymlManual onlyFast-lane: commit + push → aggressive queue clear → priority dispatch
flush-active-watchdog.ymlworkflow_run: completedClears FLUSH_ACTIVE=false whenever Flush Lifecycle Manager or any critical-deploy workflow completes — prevents stuck mutex after force-cancel

Priority tiers — single source of truth in config/workflow-priority-tiers.yml:

  • Tier 1 CRITICAL — never cancelled (token rotation, queue/reserve management, config validation)
  • Tier 2 HIGH — mirror chain, sync operations
  • Tier 3 MEDIUM — READMEs, CI checks (default for unknown workflows)
  • Tier 4 LOW — translation, dep graph, maintenance (cancelled first)

When adding a new workflow, add it to both:

  1. config/workflow-priority-tiers.yml — by workflow name: field (not filename). Both queue-manager.sh and quota-reserve.sh load tiers from this file at runtime — no script edits needed.
  2. config/workflow-sync.yml — under github_only (most workflows) or paired (if it has a GitLab CI counterpart). validate-workflow-guards.py warns on any workflow file not listed in either section.

Run python3 scripts/validate-workflow-guards.py after adding any workflow to confirm zero warnings.

dispatch-and-wait.sh exit codes:

  • 0 — workflow completed successfully
  • 1 — workflow failed or timed out
  • 2 — workflow was cancelled (by queue-manager or manually) — retriable, not a real failure

full-chain-flush.yml and critical-deploy.sh both handle exit 2 with a warning rather than aborting.

Concurrency groups

All workflows triggered by schedule or workflow_run must have a concurrency group to prevent queue pile-ups:

concurrency:
  group: workflow-name
  cancel-in-progress: true

workflow_run triggers

Each workflow should have at most one workflow_run upstream trigger. Multiple triggers cause fan-out: N completions × M downstream workflows = queue explosion.

Every name in workflow_run.workflows: must exactly match the name: field of a workflow file that actually exists in .github/workflows/. A phantom name causes the trigger to fire on every push but the job fails immediately — GitHub cannot resolve the upstream workflow. validate-workflow-guards.py (Check 5) catches this automatically.

Quota pre-flight

All hourly/daily/frequent workflows include a quota pre-flight step before doing any API work. The step sets skip=true when remaining < MIN_QUOTA and subsequent steps check if: steps.quota.outputs.skip == 'false'.

Quota cost registry

config/workflow-quota-costs.yml is the single source of truth for per-workflow REST call cost estimates. It drives:

  • quota-reserve.sh — cost-aware cancellation (min_quota per workflow)
  • budget.sh workflow_min_quota() — pre-flight helper for self-skipping
  • DOCS/quota-costs.md — rendered documentation in mdBook

Phase 1 values are code-audit estimates (basis: code-audit). Phase 2 (update-quota-costs.yml, weekly) replaces them with observed p50/p95 values (basis: observed) once ≥5 run samples exist per workflow.

When adding a new workflow that makes significant REST calls, add it to config/workflow-quota-costs.yml with estimated min_quota, cost_low, cost_mid, cost_high, and basis: code-audit. Wire qi_begin/qi_end from scripts/includes/quota-instrument.sh into its main job step so Phase 2 can measure it automatically.

Instrumented workflows (Phase 2 active):

  • Sync All Forks
  • Inject Built-with-Ona Badges
  • Reconcile Org References
  • Cleanup Stale Branches
  • Check OSP-Bound CI Status
  • Check Shell Tools CI
  • Sync Registered Imports
  • Sync Shell Tools
  • Sync UAA Vendor
  • Mirror Interested-Deving-1896 → OSP
  • Pre-Mirror CI Gate
  • Verify Mirror Integrity
  • Post-Flush Verification
  • Pipeline Telemetry
  • Translate Docs
  • Integrate Shell Tools
  • Onboard Repo
  • Critical Deploy
  • Critical Deploy — OSP
  • Critical Deploy — OOC
  • GitLab Critical Deploy
  • Critical Deploy — All (all four deploy jobs)
  • Flush Active Watchdog
  • Branch Hygiene Report
  • btrfs-devel sync
  • Delete Stale Repos

FLUSH_ACTIVE mutex

FLUSH_ACTIVE is a GitHub Actions repo variable (true/false) used as a mutex to prevent queue-manager and quota-reserve from cancelling runs during a flush pipeline. It is set by flush-lifecycle.yml and cleared by flush-active-watchdog.yml.

The force-cancel problem: If a flush run is cancelled via the GitHub UI, its always() cleanup step never executes, leaving FLUSH_ACTIVE=true permanently. Three layers defend against this:

  1. Primary — flush-active-watchdog.yml: Fires on workflow_run: completed for Flush Lifecycle Manager + all 5 critical-deploy variants. Unconditionally clears FLUSH_ACTIVE=false regardless of conclusion (success/failure/cancelled).

  2. Belt-and-suspenders — TTL check in queue-manager.sh + quota-reserve.sh: Both scripts read the variable's updated_at timestamp and treat it as unset if >8h old. A stuck mutex auto-expires even if the watchdog misses an event.

  3. Pipeline guard — scripts/includes/pipeline-guard.sh: Reusable include sourced by all critical-deploy workflows. Provides pipeline_guard_start, pipeline_guard_checkpoint, and pipeline_guard_end helpers that manage FLUSH_ACTIVE state and emit step-summary annotations.

When adding a new workflow that participates in the flush pipeline:

  • Source scripts/includes/pipeline-guard.sh and call pipeline_guard_start / pipeline_guard_end around the protected work.
  • Add the workflow's name: to flush-active-watchdog.yml's workflow_run.workflows: list.

queue-manager.sh and quota-reserve.sh FLUSH_ACTIVE check:

# Both scripts skip cancellation when FLUSH_ACTIVE=true AND updated within 8h.
# If updated_at is >8h ago the variable is treated as stale and ignored.
flush_active=$(gh api "/repos/${REPO}/actions/variables/FLUSH_ACTIVE" \
  --jq '.value' 2>/dev/null || echo "false")
flush_updated=$(gh api "/repos/${REPO}/actions/variables/FLUSH_ACTIVE" \
  --jq '.updated_at' 2>/dev/null || echo "")
# TTL check: ignore if >8h old

Pipeline guard pattern

All critical-deploy workflows use scripts/includes/pipeline-guard.sh to standardise how they interact with FLUSH_ACTIVE:

source scripts/includes/pipeline-guard.sh

# At job start — sets FLUSH_ACTIVE=true, emits step-summary header
pipeline_guard_start

# Mid-run quota check — logs remaining quota to step summary
pipeline_guard_checkpoint

# At job end (in always() step) — clears FLUSH_ACTIVE=false
pipeline_guard_end

Each critical-deploy workflow also has a sentinel job that runs in parallel with the deploy job (needs: [], if: always()). The sentinel holds a runner slot for the duration of the deploy, preventing the runner pool from being exhausted by lower-priority queued work during a critical operation.

Path filters + required status checks (gate job pattern)

When a workflow uses path filters to skip jobs on irrelevant changes, required status checks will block PRs indefinitely if the filtered jobs never run. Fix this with a gate job that always runs and reflects the filtered outcomes:

jobs:
  changes:
    name: Detect changes
    runs-on: ubuntu-latest
    outputs:
      shell: ${{ steps.filter.outputs.shell }}
    steps:
      - uses: actions/checkout@v4
      - uses: dorny/paths-filter@v3
        id: filter
        with:
          filters: |
            shell:
              - '**/*.sh'

  lint:
    name: ShellCheck
    needs: changes
    if: needs.changes.outputs.shell == 'true'
    runs-on: ubuntu-latest
    steps: [...]

  # Set THIS as the required status check — not the individual jobs above.
  ci-required:
    name: CI Required
    runs-on: ubuntu-latest
    needs: [lint]
    if: always()
    steps:
      - name: Check results
        run: |
          if echo "${{ join(needs.*.result, ' ') }}" | grep -qw "failure"; then
            exit 1
          fi

Branch protection must require CI Required (the gate job name), not the individual filtered job names. If the individual names are listed as required checks, PRs that skip those jobs will be permanently blocked.

Applied in: btrfs-dwarfs-framework/.github/workflows/ci.yaml


Autonomous-fallback mode

Consumer repos that receive the infra-core or upstream-sync profile get a bundle of operational workflows (rate-limit rerun, CI resolver, queue manager, quota reserve, notify-poller, branch cleanup) as autonomous fallbacks.

Managed mode (default): fork-sync-all is present and handles all of these centrally. The bundled workflows detect this and skip themselves.

Autonomous mode: if a consumer repo is forked independently without fork-sync-all alongside it, the bundled workflows activate and self-manage, scoped to the repo's own owner.

Mode detection (scripts/includes/fsa-mode.sh)

Three-tier hybrid check, evaluated in order:

CheckMechanismCost
BFSA_MANAGED repo variable (vars.FSA_MANAGED == 'true')0 API calls
AGET /repos/{owner}/fork-sync-all — 200 = managed1 API call
CToken owner's fork-sync-all existence (tiebreaker)2 API calls

sync-template.sh sets FSA_MANAGED=true as a repo Actions variable on every successful consumer sync via PUT /repos/{owner}/{repo}/actions/variables/FSA_MANAGED.

Adding the guard to a workflow

- name: Check FSA mode
  id: fsa
  env:
    GH_TOKEN: ${{ secrets.SYNC_TOKEN }}
    FSA_MANAGED: ${{ vars.FSA_MANAGED }}
    REPO_OWNER: ${{ github.repository_owner }}
  run: |
    source scripts/includes/fsa-mode.sh
    if fsa_is_managed; then
      echo "managed=true" >> "$GITHUB_OUTPUT"
      echo "Managed by fork-sync-all — skipping."
    else
      echo "managed=false" >> "$GITHUB_OUTPUT"
    fi

# Then on work steps:
- name: Do work
  if: steps.fsa.outputs.managed == 'false'

For workflows without a checkout (e.g. notify-poller.yml), inline the three-tier check directly in the step's run: block rather than sourcing fsa-mode.sh. See notify-poller.yml for the canonical inline implementation. The inline version replicates checks B → A → C using curl and python3.

Node identity (fsa-node-identity.sh)

scripts/includes/fsa-node-identity.sh extends fsa-mode.sh (managed/autonomous binary) with a position layer — each instance knows where it sits in the mirror chain and adjusts which operations it runs accordingly.

Three positions:

PositionDetected whenWrite operations
sourceGITHUB_REPOSITORY == Interested-Deving-1896/fork-sync-allAll
mirrorFSA_MANAGED=true + non-canonical owner, or FSA_UPSTREAM_OWNER setMirror-to-github, mirror-to-gitlab only
downstream-forkNo upstream FSA detectedAll (scoped to own org)

Mirror nodes skip source-only operations (readmes, badges, fork-sync, templates, translate) to prevent duplicate work across the chain.

Detection order (first match wins):

  1. Explicit FSA_CHAIN_POSITION env var override
  2. GITHUB_REPOSITORY matches canonical slug (Interested-Deving-1896/fork-sync-all)
  3. FSA_UPSTREAM_OWNER env var set → mirror
  4. fsa_is_managed() returns true + non-canonical owner → mirror
  5. Default → downstream-fork

Exported variables (also written to GITHUB_OUTPUT):

  • FSA_NODE_POSITIONsource | mirror | downstream-fork
  • FSA_NODE_OWNER — the org this instance manages
  • FSA_UPSTREAM_OWNER — the org being mirrored from (empty for source/fork)
  • FSA_CHAIN_DEPTH — 0=source, 1=first mirror, 2=downstream-fork

Capability predicates — return 0 (true) or 1 (false):

fsa_can_mirror_to_github   # push repos to a downstream GitHub org
fsa_can_mirror_to_gitlab   # push repos to a GitLab group
fsa_can_update_readmes     # write README files (source + fork only)
fsa_can_inject_badges      # inject badges (source + fork only)
fsa_can_sync_forks         # sync upstream forks (source + fork only)
fsa_can_translate          # run translation (source + fork only)
fsa_can_manage_templates   # push templates to consumers (source + fork only)

Usage:

source scripts/includes/fsa-node-identity.sh
fsa_node_detect
fsa_node_summary   # prints position + active capabilities to stderr

fsa_can_update_readmes && bash scripts/update-readmes.sh

Override env vars (set in workflow env: block):

  • FSA_CHAIN_POSITION — force a specific position (skips all detection)
  • FSA_UPSTREAM_OWNER — declare the upstream org (triggers mirror detection)
  • FSA_CANONICAL_OWNER — override the canonical source org (default: Interested-Deving-1896)

Scope narrowing in autonomous mode

Workflows that are org-wide in managed mode narrow their scope in autonomous mode:

WorkflowManaged scopeAutonomous scope
resolve-failures.ymlI-D-1896 (OSP-bound) + OSP + OOCgithub.repository_owner only
cleanup-branches.ymlI-D-1896 + OSP + OOCgithub.repository_owner only
queue-manager.ymlgithub.repository (already scoped)same
quota-reserve.ymlgithub.repository (already scoped)same
rate-limit-rerun.ymlgithub.repository_owner/namesame

Template manifest — source:dest remap syntax

Include entries in config/template-manifest.yml support a source:dest remap:

include:
  - assets/docs-scaffold/SUMMARY.md:DOCS/SUMMARY.md   # read from assets/, write to DOCS/
  - scripts/write-summary.sh                           # plain entry: source == dest

sync-template.sh splits on the first : — the left side is the path relative to the template root (read), the right side is the path written into the target repo. Plain entries (no :) write to the same path.

Scaffold-only behaviour: entries whose source starts with assets/docs-scaffold/ are skipped if the destination file already exists in the target repo. This prevents overwriting a consumer's existing DOCS/ content on subsequent syncs.

Devcontainer template propagation

devcontainer.template.json and automations.template.yaml are propagated to consumer repos via source:dest remaps in config/template-manifest.yml. Both are scaffold-only — skipped if the destination already exists in the consumer.

include:
  - .devcontainer/devcontainer.template.json:.devcontainer/devcontainer.json
  - .devcontainer/automations.template.yaml:.ona/automations.yaml

These entries are present in the infra-core, upstream-sync, standalone, and shell-tools profiles. The .devcontainer/ directory is otherwise excluded from template sync (it contains fork-sync-all-specific config that consumers should not receive).

Template divergence rule: devcontainer.template.json and the live .devcontainer/devcontainer.json must stay in sync. When updating either:

  • Pin headroom-ai to a specific version in both files
  • Keep --no-ccr-inject-tool in the headroom proxy start command in both automations.template.yaml and .ona/automations.yaml
  • Run python3 scripts/devcontainer-validate.py to catch divergences

Devcontainer feature — git-platform-clis

.devcontainer/features/git-platform-clis/ is a devcontainer feature that installs CLIs for all major git hosting platforms.

Installed by default: gh (GitHub CLI), glab (GitLab CLI), tea (Gitea CLI)

Optional via feature options: hub (legacy GitHub CLI), bb (Bitbucket CLI), forgejo-cli (Forgejo/Gitea v1.21+ API client) — all false by default.

Referenced in devcontainer.json and devcontainer.template.json by local path. When published to GHCR via devcontainer-sdk.yml publish mode, consumers can reference it by URI: ghcr.io/Interested-Deving-1896/fork-sync-all/git-platform-clis:1

The feature has not yet been published to GHCR. Until a publish run completes, only local path references work. Run devcontainer-sdk.yml with mode: publish to push it.

Devcontainer feature — sync-in-server

.devcontainer/features/sync-in-server/ installs the Sync-in server binary at container build time from github.com/Sync-in/server releases.

Binary resolution order in services/sync-in/start.sh (hybrid A→B→C→D):

StepPathWhen
A/usr/local/bin/sync-in-serverFeature ran at build time
B~/.local/bin/sync-in-serverpostCreateCommand ran services/sync-in/install.sh
CPATH searchBinary installed by other means
DSelf-installDownloads latest release from GitHub at service start time

If all four fail, the service exits with a clear message and suggests running the Install Sync-in Server automation task.

services/sync-in/install.sh is the shared install helper used by both postCreateCommand (B) and the automations task (C). It skips silently if the binary is already present; set FORCE=true to reinstall.

Both services/sync-in/start.sh and services/sync-in/install.sh are scaffold-only includes in all four template manifest profiles — consumers receive them on first sync, subsequent syncs skip them if already present.

Sync-in workflow (sync-in.yml)

Manages the Sync-in server/client lifecycle. Every devcontainer starts a local Sync-in server automatically via the sync-in-server automation service (port 3284, admin token at ~/.local/share/sync-in/.admin_token).

Enable/disable toggle — vars.SYNC_IN_ENABLED:

Set as a repo Actions variable (not a secret — it's plain text):

# Enable
gh api --method POST /repos/{owner}/{repo}/actions/variables \
  -f name="SYNC_IN_ENABLED" -f value="true"

# Disable (maintenance mode)
gh api --method PATCH /repos/{owner}/{repo}/actions/variables/SYNC_IN_ENABLED \
  -f value="false"

Decision matrix in secrets-check job:

ConditionResult
force_run=true (dispatch input)Run — bypasses everything
SYNC_IN_ENABLED == 'false'Skip — explicit opt-out
SYNC_IN_ENABLED == 'true'Run — explicit opt-in
SYNC_IN_ENABLED unsetRun if both secrets present, skip otherwise

Required secrets (only needed when SYNC_IN_ENABLED=true):

  • SYNC_IN_SERVER_URL — public URL of the Sync-in instance (must be reachable by GitHub Actions runners — localhost:3284 only works from inside the container)
  • SYNC_IN_ADMIN_TOKEN — admin token from ~/.local/share/sync-in/.admin_token

Federated meshconfig/sync-in-peers.yml is the peer registry. Each entry declares a node's node_id, secret names for its URL and token, role (server/client/both), and managed orgs. The register-with-peers action in sync-in-client.sh announces this node to each peer's /api/v1/peers endpoint. Dispatch with role=register-peers or role=all.

Devcontainer SDK workflow (devcontainer-sdk.yml)

Three modes, selectable via workflow_dispatch:

ModeTriggerWhat it does
validateAuto on push to .devcontainer/Runs devcontainer-validate.py — checks JSON validity, template divergence, feature schema
buildManualBuilds the devcontainer image and pushes to GHCR as an OCI artifact
publishManualPublishes features from .devcontainer/features/ to GHCR so consumers can reference by URI

Supporting scripts: scripts/devcontainer-validate.py, scripts/devcontainer-build.sh, scripts/devcontainer-publish-features.sh, scripts/devcontainer-base-image.py.

Verify Fork Integrity

verify-fork-integrity.yml / scripts/verify-fork-integrity.sh — single-repo equivalent of verify-mirror-integrity.yml. Compares this repo's default-branch HEAD against its upstream (fork parent or upstream_override).

Upstream resolution order:

  1. inputs.upstream_override (workflow dispatch input)
  2. .ota/config.yml upstream_override field
  3. GitHub fork parent API field (auto-detected)

Returns status: identical | ahead | behind | diverged. Set BLOCK_ON_DRIFT=true to exit 1 on behind or diverged.

OTA system — autonomous upstream resolution

Both ota-self-update.yml and ota-opt-in.yml now resolve their upstream dynamically rather than hardcoding Interested-Deving-1896/fork-sync-all:

PrioritySource
1upstream_override in .ota/config.yml
2GitHub fork parent API (/repos/{owner}/{repo}parent.full_name)
3Fallback: Interested-Deving-1896/fork-sync-all

ota-opt-in.yml writes the resolved upstream into .ota/config.yml as upstream_override so subsequent ota-self-update.yml runs use Check 1 (zero API calls for resolution).

ota-opt-in.yml opens the registration issue against the resolved upstream repo (not hardcoded fork-sync-all). The upstream repo must have an ota-registration label and a config/ota-registry.yml for the issue to be actionable.

resolve-failures.sh — EXCLUDED_REPOS convention

EXCLUDED_REPOS in scripts/resolve-failures.sh is intentionally empty. The resolver appends [skip ci] to every fix commit, which prevents CI re-triggers in all standard repos. Only add a repo to EXCLUDED_REPOS when [skip ci] is genuinely insufficient — for example, a repo with a push hook that ignores [skip ci] and would cause an infinite fix→trigger→fail→fix loop.

README & repo description management — autonomous single-repo mode

In autonomous mode (fork-sync-all not present), README workflows scope to the current repo only:

  • update-readmes.sh: set SINGLE_REPO=<repo-name> to bypass the org fetch and process exactly one repo. update-readmes.yml sets this automatically via the FSA mode check.
  • translate-readmes.sh: SCOPE=single sets REPOS to the current repo name (extracted from GITHUB_REPOSITORY). translate-readmes.yml sets this automatically in autonomous mode.

resolve-failures.sh — rate-limit rerun

Before sending a failed run to the AI fixer, resolve-failures.sh calls rerun_if_rate_limited(), which checks job logs for rate-limit signal patterns and re-triggers via POST /repos/{owner}/{repo}/actions/runs/{id}/rerun-failed-jobs. This covers all three orgs (I-D-1896 OSP-bound, OSP, OOC). The loop guard checks for "rate_limit_rerun": "true" in the step summary — a second rate-limit failure is logged but not re-triggered again.


Template sync profiles

config/template-consumers.yml controls which repos receive automatic file updates from sync-template.yml. Each consumer has a profile that determines what gets injected.

Profile assignments

ProfileWhat it injectsWho should use it
fullEverything — all workflows, scripts, configfork-sync-all only
mirrorMirror/sync workflows + infra toolingNobody — deprecated, do not assign
infra-corePR automation, token rotation, token health, README render validation + full autonomous-fallback suite (rate-limit rerun, CI resolver, queue/quota management, branch cleanup, PR rebase, dep updates, OTA self-management, README & repo description management, mdBook deploy/translate, fork integrity check) — dormant when fork-sync-all is presentConsumer repos that are targets of the mirror chain
standalonePR automation + token rotation onlyExternal project forks (KDE Invent, etc.)
upstream-syncinfra-core contents + upstream sync workflow and scriptRepos that track upstream projects via a registry file

Critical rule

Never assign mirror profile to consumer repos. The mirror profile injects the full fork-sync-all mirror/sync suite (60+ workflow files, 100+ scripts) into repos that are targets of the mirror chain, not operators of it. This causes template pollution — files that have no purpose in the target repo and clutter its .github/workflows/ and scripts/ directories.

Template pollution cleanup

If a repo has been polluted by the mirror profile:

  1. Check which files don't belong:
for f in .github/workflows/*.yml; do
  grep -q "SYNC_TOKEN\|openos-project\|mirror-to-osp\|registered-imports" "$f" \
    && echo "POLLUTION: $(basename $f)" \
    || echo "native:    $(basename $f)"
done
  1. Remove them with git rm --cached and commit:
git rm --cached .github/workflows/add-mirror-repo.yml  # etc.
git commit -m "chore: remove fork-sync-all template pollution"
  1. Delete the untracked files from disk:
git status --short | grep "^??" | awk '{print $2}' | xargs rm -f
  1. Trigger cleanup-pollution.yml (workflow_dispatch) to clean remaining consumer repos automatically.

Repos cleaned of mirror pollution (2026-06-06)

  • KPort — 74 files removed
  • btrfs-dwarfs-framework — 133 files removed
  • All other infra-core consumers — cleaned via cleanup-pollution.yml

Queue pile-up pattern

Workflows that trigger on .github/workflows/** (e.g. validate-config, update-workflow-triggers-doc) must have concurrency: cancel-in-progress: true to prevent stacking. Without it, rapid pushes create a queue of identical runs that consume quota on every reset, causing a deadlock where the queue can't drain because quota is always 0.

concurrency:
  group: workflow-name-${{ github.ref }}
  cancel-in-progress: true

Brandable backend

config/brand.yml allows fork-sync-all to be adopted as a white-label subsystem. When brand.enabled=true, sync-template.sh substitutes {{FSA_*}} tokens in propagated file content with the consumer's own identity values.

Default state: brand.enabled=false — no behaviour change until a consumer explicitly opts in by setting enabled: true in their own config/brand.yml.

Substitution tokens

TokenFieldExample
{{FSA_NAME}}brand.namefork-sync-all
{{FSA_SLUG}}brand.slugfsa
{{FSA_ORG}}brand.orgInterested-Deving-1896
{{FSA_REPO}}brand.repofork-sync-all
{{FSA_DESCRIPTION}}brand.descriptionone-line description
{{FSA_SUPPORT_URL}}brand.support_urlsupport/docs URL

Applying brand substitution

scripts/apply-brand.py reads config/brand.yml and rewrites tokens in a target file. Called by sync-template.sh after writing each propagated file when brand.enabled=true.

python3 scripts/apply-brand.py path/to/file.yml

skin.files overrides

The skin.files list in config/brand.yml maps source files to destination paths in consumer repos, applied after the profile include list. Entries are scaffold-only by default (scaffold_only: true). Set scaffold_only: false to always overwrite.


Git subtree / submodule / umbrella scaffold

config/subtree-manifest.yml declares three relationship types between this repo and external repos. scripts/manage-subtrees.sh implements all operations. manage-subtrees.yml runs weekly (Sunday 01:00 UTC) and on manual dispatch.

Relationship types

TypeMechanismBest for
subtreegit subtree add/pull — remote history merged under a prefix dir, no .gitmodulesVendored upstream code you modify locally
submoduleStandard git submodule — pinned SHA, .gitmodules entry, pointer not copyExternal deps you consume but don't modify
umbrellaThis repo as super-repo — aggregates child repos as submodules under umbrella.prefix/Monorepo-style development across org repos

manage-subtrees.sh commands

bash scripts/manage-subtrees.sh sync          # pull all subtrees + update all submodules
bash scripts/manage-subtrees.sh add <name>    # add a new subtree/submodule from manifest
bash scripts/manage-subtrees.sh status        # show drift vs upstream for all entries
bash scripts/manage-subtrees.sh umbrella-init # initialise umbrella children as submodules

Adding a new entry

Add to the appropriate list in config/subtree-manifest.yml, then run manage-subtrees.sh add <name>. Do not run git subtree add or git submodule add manually — the script handles squash flags, shallow clones, and .gitmodules consistency.

Nested submodule policy

nested.recurse=false by default. Enable only when a submodule itself has submodules you need. nested.max_depth=2 prevents runaway recursion.


OSP-bound repo list

The canonical list of ~49 repos that are mirrored to GitLab lives in config/gitlab-subgroups.yml. Parse it with yaml.safe_load — do not hardcode repo names anywhere else.

To get the list in bash:

python3 -c "
import yaml
data = yaml.safe_load(open('config/gitlab-subgroups.yml'))
for sg in data.get('subgroups', {}).values():
    for repo in (sg.get('repos') or []):
        print(repo)
"

GitLab subgroup IDs

OSP leg — openos-project (gitlab.com/openos-project)

Subgroup slugGitLab ID
git-management_deving130516820
penguins-eggs_deving130516402
immutable-filesystem_deving130516465
linux-kernel_filesystem_deving130516188
incus_deving130516536
taubyte_deving133909500
neon-deving130739746
ops130734009
yaml-tooling_deving133909501
cachyos_deving133909503
ai-agents_deving133909504
rust-systems_deving133954601
accessibility_deving134613311
agnostic-api_deving134613312

All IDs are authoritative — sourced from config/gitlab-subgroups.yml. Do not hardcode them elsewhere.

OOC leg — openos-project-ooc-ecosystem (gitlab.com/openos-project-ooc-ecosystem)

Root group ID: 134901804

OOC subgroup names mirror OSP exactly — same slugs, different GitLab group. Config: config/gitlab-subgroups-ooc.yml.

Subgroup slugGitLab ID
git-management_deving134918116
penguins-eggs_deving134918117
immutable-filesystem_deving134918118
linux-kernel_filesystem_deving134918121
incus_deving134918123
taubyte_deving134918126
neon-deving134918128
ops134918131
yaml-tooling_deving134918134
cachyos_deving134918136
ai-agents_deving134918137
rust-systems_deving134918138
accessibility_deving134918140
agnostic-api_deving134918142
projects (fallback)134901804

All IDs are authoritative — sourced from config/gitlab-subgroups-ooc.yml.

Subgroup mirroring convention: when adding a new subgroup to the OSP config, add the same slug to the OOC config with id: null and repos: []. The two repos: lists are populated independently — OSP repos and OOC repos are distinct even when they share a subgroup name.


README & Repo Description Management

AI marker format

<!-- AI:start:section-name -->
content
<!-- AI:end:section-name -->

Eight AI-owned sections: what-it-does, architecture, ci, mirror-chain, contributors, origins, resources, license.

Human-owned sections (Install, Usage, Configuration, License) never get AI markers — they get placeholder HTML comments on first creation.

Three modes in update-readmes.sh

  • rewrite — no AI markers present → build full template from scratch
  • fill — some markers present but missing sections → inject missing ones
  • update — all markers present → regenerate AI section content

check-readme-render.sh

Run this against any README before committing. It catches: leaked log lines, unclosed fences, unclosed AI markers, empty sections, missing H1, broken tables, bare [text] links, raw angle brackets.

bash scripts/check-readme-render.sh path/to/README.md

Per-file repo descriptions (generate-repo-descriptions.sh)

Generates a one-line AI description for every file in a repo and commits the results to DESCRIPTIONS.md. Uses GitHub Models (gpt-4o-mini by default — high volume, short outputs, no frontier reasoning needed).

Inspired by ioncakephper/repo-description — reimplemented using llm.sh (GitHub Models) instead of Groq + Node.js.

Output format (DESCRIPTIONS.md):

# File Descriptions
<!-- AI:generated -->

| File | Description |
|---|---|
| `scripts/sync-forks.sh` | Syncs all upstream forks via the GitHub merge-upstream API |
| `config/gitlab-subgroups.yml` | Maps OSP-bound repos to their GitLab subgroup placement |

Workflow: generate-repo-descriptions.yml — runs weekly (Sunday 03:30 UTC), dispatches manually with target_repo, model, max_files, file_filter inputs. SKIP_EXISTING=true by default so incremental runs only describe new files.

Key env vars:

  • TARGET_REPO — repo to describe (defaults to fork-sync-all itself on schedule)
  • MAX_FILES — cap per run (default: 200) to control quota consumption
  • MODEL — override model (default: openai/gpt-4o-mini)

Repo settings management (manage-repo-settings.sh)

Declarative repo settings drift detection and enforcement across all OSP-bound repos. Reads config/repo-settings.yml and either reports drift (check mode) or enforces declared state (apply mode) via the GitHub REST API.

Inspired by andrewthetechie/gha-repo-manager — reimplemented as a shell script using gh-api.sh + budget.sh infrastructure.

Settings file: config/repo-settings.ymldefaults block applies to all repos, overrides block provides per-repo overrides, skip list excludes repos.

Supported fields: description, homepage, has_issues, has_projects, has_wiki, has_discussions, allow_squash_merge, allow_merge_commit, allow_rebase_merge, allow_auto_merge, delete_branch_on_merge, squash_merge_commit_title, squash_merge_commit_message, topics, vulnerability_alerts.

Workflow: manage-repo-settings.yml — runs weekly in check mode (Monday 04:30 UTC). Apply mode is manual-only (workflow_dispatch with mode: apply) to prevent accidental bulk changes.

API cost: 1 REST call per repo in check mode. 1–3 REST calls per drifted repo in apply mode (PATCH settings + PUT topics + PUT/DELETE vulnerability alerts).


GitLab CI variables

These must be set as masked CI/CD variables in the openos-project/fork-sync-all GitLab project settings (not GitHub secrets):

VariableMaps toUsed byNotes
GITLAB_TOKENGITLAB_TOKEN GitHub secretMost GitLab CI jobsapi + read_repository + write_repository scope
WORKFLOW_SECRETSYNC_TOKEN GitHub secretsync-forks, notify-poller, resolve-failures, rate-limit-rerun, token-health, cleanup-branchesGitHub PAT with repo + workflow + admin:org scopes
GH_SYNC_TOKENGH_SYNC_TOKEN GitHub secretsync-from-gitlabGitHub PAT with repo + workflow scopes
GITLAB_MAINTENANCE_TOKENmaintain:storageInherited from openos-project group variable; api scope on GitLab

Headroom proxy

A context compression proxy runs on port 8787 (started automatically via .ona/automations.yaml). To use it with Claude:

ANTHROPIC_BASE_URL=http://localhost:8787 claude
# or
headroom wrap claude

Check savings: headroom stats


Token rotation

Tracked tokens

The "PAT name" column is the display name shown at github.com/settings/tokens (classic).

SecretPAT nameScopePlatform / OrgExpiryUsed byRotate via
SYNC_TOKENfork-sync-all SYNC_TOKENadmin:org, admin:org_hook, admin:repo_hook, audit_log, delete:packages, delete_repo, gist, notifications, project, repo, workflow, write:packagesGitHub / I-D-18962026-09-02Most workflowsrotate-token.yml
GH_SYNC_TOKENsync-mirror-watchdogadmin:org, admin:org_hook, admin:public_key, admin:repo_hook, audit_log, gist, notifications, project, repo, workflow, write:discussion, write:packagesGitHub / I-D-18962026-09-03mirror workflowsrotate-token.yml
OSP_ADMIN_TOKENOSP_ADMIN_TOKENadmin:orgGitHub / OpenOS-Project-OSP2026-09-03rotate-token.yml (OSP org secret rotation)rotate-token.yml
MIRROR_TOKENOSP-ORG Mirror Tokenadmin:enterprise, admin:gpg_key, admin:org, admin:org_hook, admin:public_key, admin:repo_hook, admin:ssh_signing_key, project, repo, workflowGitHub / OpenOS-Project-OSP2026-09-01mirror workflowsrotate-token.yml
ORG_MIRROR_OSP_TO_OOCOSP-ORG Mirror Token(same PAT as MIRROR_TOKEN)GitHub / OpenOS-Project-OSP2026-09-01mirror-osp-to-ooc.yamlrotate-token.yml
ADD_MIRROR_REPO_SYNCfork-sync-all-onaadmin:repo_hook, read:org, repo, workflowGitHub / I-D-18962026-08-13 ⚠️add-mirror-repo.ymlrotate-token.yml
GITLAB_SYNC_TOKENfork-sync-all-syncapi, read_repository, write_repositoryGitLab / openos-project2027-05-13sync-to-gitlab.yml, mirror-osp-to-gitlab.yml, sync-from-gitlab.ymlrotate-token.yml
GITLAB_TOKENOna-Env-SecretapiGitLab / openos-project2027-05-17Ona dev environment (injected as GITLAB_TOKEN env var); also used by gl-storage-scan, sync-to-gitlab-variant, cleanup-pollution, reconcile-org-refsrotate-token.yml
BITBUCKET_TOKENn/a (opt-in)Bitbucket APIBitbucketunknownsync-registered-imports.yml, clone-org.yml, import-repo.yml — skipped if unsetrotate-token.yml
GITEA_TOKENn/a (opt-in)Gitea APIGitea instanceunknownsync-registered-imports.yml, clone-org.yml, import-repo.yml — skipped if unsetrotate-token.yml

| ACTIVITYSMITH_API_KEY | n/a (external service) | ActivitySmith API | ActivitySmith | unknown | full-chain-flush.yml (live activity tracking) — optional, skipped if unset | manual | | ACTIVITYSMITH_CHANNELS | n/a (external service) | ActivitySmith channel IDs | ActivitySmith | n/a | full-chain-flush.yml — optional, skipped if unset | manual | | ANTHROPIC_API_KEY | n/a (external service) | Anthropic API | Anthropic | n/a | validate-config.yml (AgentShield scan) — optional, skipped if unset | manual |

How to rotate a repo secret (SYNC_TOKEN, GH_SYNC_TOKEN, etc.)

  1. Generate a new PAT at https://github.com/settings/tokens
  2. Go to rotate-token.ymlRun workflow
  3. Select the secret name from the dropdown
  4. Paste the new token value into the token_value field
  5. Leave validate checked — it confirms the token works before finishing
  6. After the run completes, update the expiry date in this table

How to rotate an OSP org secret (ORG_MIRROR_OSP_TO_OOC, MIRROR_TOKEN)

OSP org secrets live in OpenOS-Project-OSP and require a token with admin:org on that org. SYNC_TOKEN only covers Interested-Deving-1896.

The rotate-token.yml workflow resolves the OSP token automatically in this priority order:

Option 1 — GitHub App (preferred, permanent)

A GitHub App installation token never expires and has fine-grained permissions.

One-time setup:

  1. Create a GitHub App at https://github.com/settings/apps/new
    • Name: fork-sync-all-osp-rotator (or similar)
    • Permissions: Organization secrets → Read and write
    • Uncheck everything else
  2. Install the App on OpenOS-Project-OSP org
  3. Note the App ID (shown on the app settings page)
  4. Generate a private key (PEM format) from the app settings page
  5. Add two repo secrets to Interested-Deving-1896/fork-sync-all:
    • OSP_APP_ID — the numeric App ID
    • OSP_APP_PRIVATE_KEY — the full PEM contents (including header/footer)
  6. Run rotate-token.yml — it will use the App automatically

Option 2 — Dedicated PAT (bridge until App is set up)

  1. Generate a new PAT at https://github.com/settings/tokens with:
    • admin:org scope
    • Authorized for OpenOS-Project-OSP org (SSO authorize if required)
  2. Add it as repo secret OSP_ADMIN_TOKEN in Interested-Deving-1896/fork-sync-all
  3. Run rotate-token.yml — it will use OSP_ADMIN_TOKEN automatically

Option 3 — Manual fallback

If neither OSP_APP_* nor OSP_ADMIN_TOKEN is set, the workflow prints the exact error and the two options above. You can also update manually:

  1. Generate a new PAT with admin:org on OpenOS-Project-OSP
  2. Go to OSP org secrets and update the secret value directly
  3. Update the expiry date in scripts/token-monitor.sh (OSP_ORG_SECRETS array) and in the table above

⚠️ Upcoming rotations (as of 2026-06-08):

  • ADD_MIRROR_REPO_SYNC — expires 2026-08-13 (66 days). token-health.yml will open an issue around 2026-06-29.
  • MIRROR_TOKEN / ORG_MIRROR_OSP_TO_OOC — expire 2026-09-01 (85 days). Alert ~2026-07-17.
  • SYNC_TOKEN — expires 2026-09-02 (86 days). Alert ~2026-07-18.
  • GH_SYNC_TOKEN / OSP_ADMIN_TOKEN — expire 2026-09-03 (87 days). Alert ~2026-07-19.

Automated monitoring

token-health.yml runs weekly (Monday 09:00 UTC) and warns at 45 days before expiry. When a token needs attention it opens a GitHub issue labelled token-monitor. Run it manually at any time to get a current status report.


vendor/ conventions

Agnostic-by-default rule

Everything imported into vendor/ must be deployment-agnostic. No distro names, org-specific URLs, org/repo slugs, or arch/repo paths may appear as hardcoded fallback values in shell ${VAR:-...}, YAML || '...', or TypeScript ?? '...' expressions. All deployment-identity values belong in CI variables or repo vars set per deployment.

Enforcement

scripts/check-vendor-agnostic.sh scans a vendor directory and exits 1 on violations:

bash scripts/check-vendor-agnostic.sh vendor/infra-dashboard   # specific component
bash scripts/check-vendor-agnostic.sh vendor                   # all of vendor/

enforce-agnostic-vendor.yml runs this automatically on every push/PR touching vendor/.

To suppress a specific line that is intentionally non-agnostic:

SOME_VAR="${SOME_VAR:-specific-value}"  # check-vendor-agnostic: ignore

What the checker flags vs. allows

Flagged (deployment-identity):

  • Public URLs as fallbacks: ${VITE_ENDPOINT_URL:-https://api.myorg.com}
  • Org/repo slugs: ${MIRRORLIST_REPO:-MyOrg/my-repo}
  • Arch/repo paths: ${MIRROR_REPO_PATHS:-x86_64/core,x86_64/extra}
  • Bare distro names: ${DISTRO:-cachyos}, ${DISTRO:-ubuntu}

Allowed (generic defaults):

  • Localhost dev URLs: ${API_URL:-http://localhost:5862}
  • Generic relative paths: ${MIRRORLIST_PATH:-mirrorlist/mirrorlist}
  • Single-word tokens: ${LOG_LEVEL:-info}, ${ENV:-production}
  • UI strings: ${APP_NAME:-Infra Dashboard}

Workflow integrations

import-repo → immediate sync

When ongoing_sync=true, import-repo.sh writes to registered-imports.json and then immediately dispatches sync-registered-imports.yml with repo_filter=<name> and force_sync=true. This avoids the up-to-6h wait for the scheduled run to pick up the new entry.

If the dispatch fails (quota, permissions), it falls back gracefully — the entry is still registered and will sync on the next scheduled run.

merge-to-monorepo → OSP mirror chain

merge-to-monorepo.yml has a mirror_monorepo boolean input (default: false). When set, it dispatches add-mirror-repo.yml for the newly created monorepo after a successful merge, entering it into the standard OSP mirror chain automatically.


Action version pinning

Canonical versions (verified 2026-06-24). Use these exactly — do not downgrade, do not guess from memory.

ActionVersion
actions/checkout@v7
actions/setup-python@v6
actions/setup-node@v6
actions/cache@v6
actions/cache/save@v6
actions/upload-artifact@v7
actions/download-artifact@v8
actions/upload-pages-artifact@v5
actions/deploy-pages@v5
actions/labeler@v6
actions/github-script@v9

Before adding a new action or bumping a version, verify with:

curl -sf "https://api.github.com/repos/actions/checkout/releases/latest" \
  -H "Authorization: token $GH_TOKEN" \
  | python3 -c "import json,sys; print(json.load(sys.stdin)['tag_name'])"

History: This repo has had repeated bulk regressions from agents writing versions from memory. checkout moved v4→v5→v6→v7 across sessions; each transition caused a mass failure. The table above is the single source of truth — update it here when versions change, then do a bulk find-replace across .github/workflows/.

GitHub Actions expression and permissions constraints

These are constraints GitHub's own validator enforces that pyyaml does not catch locally. All three produce the same symptom: the run shows "This run likely failed because of a workflow file issue" with 0s duration — the runner never starts.

Diagnose with:

gh workflow run <workflow-file>.yml --repo <owner>/<repo> [--field key=val]
# HTTP 422 response body contains the exact line/col and error message

Secrets not allowed in if: conditions

# ❌ GitHub rejects this — secrets context unavailable in if: expressions
- name: Deploy via SSH
  if: ${{ secrets.SSH_KEY != '' }}

# ✅ Use an env var and branch in the run: block instead
- name: Deploy
  env:
    SSH_KEY: ${{ secrets.SSH_KEY }}
  run: |
    if [[ -n "$SSH_KEY" ]]; then
      # SSH path
    else
      # fallback path
    fi

Invalid permissions: scopes

GitHub Actions only accepts a specific set of permission scopes. secrets and variables are not valid — they will cause a parse failure.

# ❌ Both of these are rejected
permissions:
  secrets: write
  variables: write

# ✅ Valid scopes only
permissions:
  contents: read
  actions: read
  # Full list: actions, checks, contents, deployments, id-token, issues,
  # discussions, packages, pages, pull-requests, repository-projects,
  # security-events, statuses, workflows

Note: writing repo variables requires the actions: write scope (via the Actions API), not a dedicated variables scope.

Dynamic step outcome access (steps[var].outcome)

GitHub Actions expressions do not support dynamic property access via variables. steps[check].outcome where check is a shell variable is rejected.

# ❌ Rejected — dynamic bracket access not supported
- name: Summarise
  run: |
    for check in check_yaml check_guards; do
      result="${{ steps[check].outcome }}"
    done

# ✅ Pass all step outcomes via toJSON(steps) and read with python3
- name: Summarise
  env:
    STEPS_JSON: ${{ toJSON(steps) }}
  run: |
    for check in check_yaml check_guards; do
      result=$(echo "$STEPS_JSON" | python3 -c \
        "import json,sys; d=json.load(sys.stdin); print(d.get('${check}',{}).get('outcome','skipped'))")
    done

workflow_run trigger + reusable workflow call (uses:)

GitHub prohibits calling a reusable workflow from a workflow_run-triggered workflow. The combination produces startup_failure (0s duration, "workflow file issue") even though the YAML is syntactically valid and pyyaml accepts it.

# ❌ startup_failure — workflow_run + reusable call is forbidden
on:
  workflow_run:
    workflows: ["Validate Config"]
    types: [completed]
jobs:
  guard:
    uses: ./.github/workflows/pr-lifecycle-guard.yml  # NOT allowed

Fix: inline the reusable workflow's logic as steps in the calling job. schedule and workflow_dispatch triggers are unaffected — only workflow_run has this restriction.

Detection: scan for the combination with:

python3 -c "
import re, pathlib
for wf in pathlib.Path('.github/workflows').glob('*.yml'):
    c = wf.read_text()
    if re.search(r'^\s+workflow_run:', c, re.MULTILINE) and \
       re.search(r'^\s{4}uses:\s+\./', c, re.MULTILINE):
        print(wf.name)
"

actions/checkout must precede quota-snapshot.sh

scripts/includes/quota-snapshot.sh sources time_format.py via a path relative to BASH_SOURCE[0]. Without actions/checkout the script file does not exist on the runner and the source call fails with No such file or directory.

Rule: in every job that sources quota-snapshot.sh, actions/checkout must be the first step.

# ✅ correct
steps:
  - uses: actions/checkout@v7
  - name: Quota pre-flight
    run: |
      source scripts/includes/quota-snapshot.sh
      quota_snapshot

# ❌ wrong — source fails before checkout runs
steps:
  - name: Quota pre-flight
    run: |
      source scripts/includes/quota-snapshot.sh   # file not found
      quota_snapshot
  - uses: actions/checkout@v7

validate-workflow-guards.py Check 7 detects this automatically. Run it after adding any new workflow that uses quota-snapshot.sh.

SUBGROUPS_CONFIG relative path and cd into work dirs

scripts/mirror-osp-to-gitlab.sh does cd "$work_dir" into a git mirror clone. Any relative path passed via env var before that cd will break.

The workflow passes SUBGROUPS_CONFIG: config/gitlab-subgroups-ooc.yml (relative). The script now resolves it to absolute at startup:

_raw="${SUBGROUPS_CONFIG:-config/gitlab-subgroups.yml}"
if [[ "${_raw}" != /* ]]; then
  GL_SUBGROUP_CONFIG="${REPO_ROOT}/${_raw}"
else
  GL_SUBGROUP_CONFIG="${_raw}"
fi

General rule: resolve any env-var path to absolute before any cd that could change the working directory.

Incus daemon and runner capabilities

The incusd service and sync-in-server service require Linux capabilities that are not available on standard Ona Cloud runners. This section documents what is needed and how to enable it.

Capability requirements

CapabilityRequired forStandard Ona CloudSelf-hosted (privileged)
CAP_SYS_ADMINnamespace creation, mount✗ missing✓ available
CAP_NET_ADMINbridge/veth, nftables✗ missing✓ available
/dev/kvmhardware-accelerated VMs✗ not present✓ if nested virt enabled
/dev/fusefuse-overlayfs rootfs✗ not present✓ available
user namespacesunprivileged containers✗ blocked✓ available

On standard Ona Cloud runners the incusd service will fail to start with CAP_SYS_ADMIN not available. The Incus client (incus CLI) is still installed and can manage remote Incus servers.

Enabling on a self-hosted runner

To run incusd locally in the devcontainer, the runner VM must:

  1. Expose capabilities — run the devcontainer with --privileged or grant CAP_SYS_ADMIN + CAP_NET_ADMIN + seccomp=unconfined.
  2. Enable nested virtualization — for KVM-accelerated VMs, the host must have vmx/svm CPU flags and expose /dev/kvm to the container. Without KVM, Incus falls back to QEMU TCG (software emulation — slower but functional for testing and image building).
  3. Expose /dev/fuse — for fuse-overlayfs rootfs driver.

On AWS, use a metal instance type (e.g. c5.metal) or an instance with nested virtualization enabled. On GCP, enable "Enable nested virtualization" in the VM configuration.

Service startup order

When the runner supports it, start services in this order:

gitpod automations service start incusd        # starts incusd, runs incus admin init --auto
gitpod automations service start sync-in-server # launches syncin/server via incus launch docker:...

sync-in-server calls incus info at startup and exits immediately if incusd is not running.

OCI image source

Sync-in/server is published to Docker Hub as syncin/server (tags: latest, 2, 2.4.1, etc.). Incus pulls it via docker:syncin/server:latest using its built-in OCI image support — no Docker daemon required.

The ./features/incus/install.sh feature detects capabilities at build time:

  • If CAP_SYS_ADMIN + CAP_NET_ADMIN are present → installs full daemon from zabbly daily channel + QEMU
  • Otherwise → installs client only from zabbly stable channel

Known pitfalls

  • fill_missing_sections case statement — must handle all 8 AI sections. If you add a new section to ALL_AI_SECTIONS, add it to the case in fill_missing_sections, rewrite_readme, and the update mode loop.

  • sync-registered-imports.sh does not create reposensure_gh_repo() handles creation now, but the target repo must be reachable via the GitHub API. New entries in registered-imports.json will auto-create the repo on first run.

  • GitLab mirror chain — two independent legs:

    • OSP leg: I-D-1896 → OpenOS-Project-OSP (GitHub) → openos-project (GitLab)
    • OOC leg: OpenOS-Project-Ecosystem-OOC (GitHub) → openos-project-ooc-ecosystem (GitLab)

    Adding a repo to gitlab-subgroups.yml (OSP) or gitlab-subgroups-ooc.yml (OOC) is required for GitLab mirroring on the respective leg. Adding to registered-imports.json is required for upstream sync. All three are independent — a repo can be in any combination.

  • _inter_repo_sleep in update-readmes.sh — quota-aware pacing. No delay when quota > 2000; scales to 30s when < 500. The cached _quota_remaining variable is decremented by 10 per repo to trigger re-checks before actually hitting the threshold.


FSA-API

fsa-api/ is a two-layer HTTP API over the fork-sync-all control plane. Full reference: fsa-api/README.md. Key conventions for agents:

Layer structure

fsa-api/uaa/          — Unified Agnostic API (generic, platform-agnostic)
fsa-api/core/         — FSA-specific adapters (GitHub-org-specific)
fsa-api/config/       — fsa-routes.yml + fsa-toggles.yml + fsa-deployments.yml
fsa-api/server/       — fsa-start.sh (merges both route files)

Never put FSA-specific logic in fsa-api/uaa/. UAA is propagated to consumer repos via sync-template.sh. FSA-specific adapters belong in fsa-api/core/adapters/<domain>/.

Adding an adapter

Every new adapter must:

  1. Source fsa-adapter.sh (not adapter.sh directly)
  2. Call fsa_quota_check N before any API calls
  3. Check its toggle with toggle_enabled <name> if the domain has one
  4. Have a route entry in fsa-api/config/fsa-routes.yml
  5. Pass python3 scripts/validate-workflow-guards.py with zero warnings
#!/usr/bin/env bash
# GET /api/fsa/<domain>/<resource>
source "$(dirname "${BASH_SOURCE[0]}")/../../lib/fsa-adapter.sh"

fsa_quota_check 50 || exit 0
toggle_enabled my_toggle || { fsa_error "disabled" 503; exit 0; }
# ... logic ...
fsa_ok '{"result":"..."}'

shared.sh — UAA ↔ FSA sync point

fsa-api/uaa/lib/shared.sh is sourced by both uaa/lib/adapter.sh and fsa-api/core/lib/fsa-adapter.sh. It contains platform-agnostic logic shared between the two layers:

  • Toggle system: toggle_get / toggle_enabled / toggle_set / toggle_list reads UAA_TOGGLES_FILE (set to fsa-api/config/fsa-toggles.yml by FSA)
  • Quota guard: quota_check N / quota_fetch — FSA overrides quota_fetch() with the GitHub-specific implementation; UAA defaults to 9999 (unlimited)
  • JSON helpers: json_ok / json_error / json_listfsa_ok / fsa_error / fsa_list are aliases kept for backward compatibility
  • Route merge: merge_routes_files FILE... — merges multiple route manifests
  • Capability registry: register_capability / list_capabilities

When adding logic that is genuinely platform-agnostic (no GitHub/GitLab coupling), add it to shared.sh so both UAA consumers and FSA adapters benefit. When adding logic that is GitHub-specific, add it to fsa-adapter.sh only.

Platform-agnostic adapters (fsa_platform_init)

fsa-adapter.sh sources scripts/includes/platform-adapter.sh. Every FSA adapter can switch platforms by calling fsa_platform_init:

fsa_platform_init gitlab          # switches to GitLab, selects GITLAB_TOKEN
pa_list_repos "openos-project"    # uses GitLab API
fsa_platform_init github          # switch back

Token selection is automatic: githubGH_TOKEN, gitlabGITLAB_TOKEN, giteaGITEA_TOKEN, forgejoFORGEJO_TOKEN, codebergCODEBERG_TOKEN.

workflows/list.sh and workflows/run.sh have platform branches for all 5 platforms. New workflow-management adapters should follow the same pattern: check PA_PLATFORM and branch accordingly.

Deployment registry (config/fsa-deployments.yml)

Single source of truth for all known FSA instances. The deployments adapter domain reads this file — do not hardcode deployment coordinates in adapters.

deployments:
  - id: source
    platform: github
    org: Interested-Deving-1896
    ...
  - id: osp-gitlab
    platform: gitlab
    group_path: openos-project/ops
    ...

When a new FSA instance is created (new org, new platform), add it here. The /api/fsa/deployments/* routes and codebase/drift will pick it up automatically.

codebase/sync dispatch rule

POST /api/fsa/codebase/sync always dispatches on the source repo (Interested-Deving-1896/fork-sync-all), never on FSA_REPO. The source workflow (sync-fsa-forks.yml) then pushes updates to all mirrors. force=true dispatches critical-deploy-gitlab.yml instead (direct git push, bypasses mirror sync chain — use for emergency GitLab mirror recovery).

Route manifest conventions

fsa-api/config/fsa-routes.yml extends the UAA route format. Fields:

- path: /api/fsa/<domain>/<resource>
  script: core/adapters/<domain>/<verb>.sh
  method: GET|POST|PUT|DELETE
  auth: true          # require FSA_API_TOKEN header (write operations)
  toggle: <name>      # gate on fsa-toggles.yml entry
  # comment describing query params or body shape

fsa-start.sh merges fsa-api/uaa/config/routes.yml + fsa-api/config/fsa-routes.yml using shared.sh's merge_routes_files(). Last writer wins on path+method conflicts.


Platform adapter (platform-adapter.sh)

scripts/includes/platform-adapter.sh provides a uniform interface for interacting with any supported git hosting platform so that sync scripts can be written once and work against any backend.

Supported platforms: github | gitlab | gitea | forgejo | codeberg

Initialisation — must be called before any other pa_* function:

PLATFORM=gitlab PLATFORM_TOKEN="$GITLAB_TOKEN" pa_init gitlab
# With self-hosted host override:
PLATFORM=gitea PLATFORM_TOKEN="$TEA_TOKEN" pa_init gitea https://gitea.myco.com

Sets PA_HOST, PA_API, PA_AUTH_HEADER, PA_CLONE_PREFIX as internal state. Guard against double-sourcing is in place (_PLATFORM_ADAPTER_LOADED).

Public functions:

FunctionPurpose
pa_init PLATFORM [HOST]Initialise adapter for the given platform
pa_list_repos ORGPrint one repo name per line; handles pagination
pa_repo_exists ORG REPOReturns 0 if repo exists, 1 otherwise
pa_clone_url ORG REPOAuthenticated HTTPS clone URL
pa_push_url ORG REPOAuthenticated HTTPS push URL (same as clone for most platforms)
pa_create_repo ORG REPO [DESC]Create repo if absent; no-op if already exists
pa_api_get URLAuthenticated GET with rate-limit retry
pa_rate_limit_remainingRemaining API quota (best-effort)

Rate-limit retrypa_api_get retries HTTP 429/403 up to 3 times with reset-aware backoff. Reads X-RateLimit-Reset (GitHub/Gitea/Forgejo) or RateLimit-Reset (GitLab) from response headers; falls back to 60s if absent.

Auth header format per platform:

  • GitHub: Authorization: token TOKEN
  • GitLab: PRIVATE-TOKEN: TOKEN
  • Gitea/Forgejo/Codeberg: Authorization: token TOKEN

Clone URL prefix per platform:

  • GitHub: https://x-access-token:TOKEN@github.com
  • GitLab: https://oauth2:TOKEN@gitlab.com
  • Gitea/Forgejo/Codeberg: https://x-access-token:TOKEN@HOST

git-platform-sync.sh is the primary consumer. It uses pa_init twice per sync leg (once for source, once for dest) and calls pa_list_repos, pa_repo_exists, pa_clone_url, pa_push_url, and pa_create_repo. The git-platform-sync.yml workflow replaces the deprecated sync-to-gitlab.yml (direction=push) and sync-from-gitlab.yml (direction=pull) — both are now no-op stubs kept only for workflow_run name resolution.


Template consumer tiers

config/template-consumers.yml has a tier field that controls whether sync-template.sh may write to a repo:

  • tier: protected — skipped in all three modes (create, inject, propagate). Used for fork-sync-all itself and all its mirrors (OSP GitHub, OOC GitHub, both GitLab groups). These repos receive updates via the mirror chain, not direct template injection. Adding a new fork-sync-all mirror: list it here with tier: protected — no script changes needed.
  • tier: managed — normal sync target (default when omitted).

The guard is enforced at three layers:

  1. scripts/sync-template.sh — reads tier from the YAML parser (line 10 of the record format); skips protected entries in all three run_ functions.
  2. .github/workflows/sync-template.ymlvalidate job calls check_protected() and rejects protected targets before any runner runs.
  3. config/template-consumers.yml — prominent comment at the top of the file.

Known pitfall: sync-template.sh CREATE mode cannot read tier from the consumers file for a repo that doesn't exist yet. It does a runtime lookup against the consumers file by name — so a new fork-sync-all mirror must be added to template-consumers.yml with tier: protected before anyone attempts to CREATE it via sync-template.


sync-template contamination — what happened and how it's prevented

In June 2026, sync-template.sh was run with fork-sync-all as a target (either CREATE or INJECT mode). Because the script runs from a fork-sync-all checkout and copies the working tree into the target, this committed ~224 eggs-ai application source files (src/, bin/, myclaw/, install.sh, package.json, etc.) directly into fork-sync-all over several weeks.

Root causes fixed:

  1. fork-sync-all was listed in template-consumers.yml as a managed consumer with profile: full — removed and replaced with tier: protected.
  2. No guard existed in the script or workflow against self-targeting — added (see Template consumer tiers above).
  3. mirror.yaml (a raw git-push mirror introduced via the contamination) was pointing at Interested-Deving-1896/eggs-ai instead of the OSP mirror — removed entirely (superseded by mirror-to-osp.yml).
  4. actions/checkout@v6 (non-existent) was in 113 workflow files — replaced with @v4 across all workflows.

If you see chore: add template file <eggs-ai-path> [skip ci] commits in the log, the contamination has recurred. The fix is to revert those commits and verify the tier guard is in place.


GitLab token scopes

Two different tokens are used for GitLab operations:

TokenEnv varScopesUsed for
GitLab read tokenGITLAB_TOKEN (Ona project secret)read_api, read_repositoryAPI reads (project metadata, branch info, commit lookup)
GitLab sync tokenGITLAB_SYNC_TOKEN (GitHub Actions secret only)api, write_repositorygit push to GitLab mirrors, project creation, branch protection

GITLAB_SYNC_TOKEN is not injected into Ona environments — it only exists as a GitHub Actions secret. Any operation that needs to push to GitLab must be done via a dispatched workflow, not directly from an agent environment.

GITLAB_TOKEN in the Ona environment has zero length if the project secret wasn't set at environment creation time. Check with echo ${#GITLAB_TOKEN}.


Auto-merge PRs

scripts/auto-merge-prs.sh merges open PRs once their required checks pass. Three hybrid detections run per PR at runtime — no static configuration needed.

Scope detection (which PRs to merge)

Priority order — first match wins:

  1. Label auto-merge present → merge (explicit opt-in)
  2. PR author login ends in [bot], or matches the SYNC_TOKEN owner → merge (automation output)
  3. AUTO_MERGE_ALL=true env var → merge all open PRs
  4. Default → skip (human PRs require explicit opt-in)

Bot detection uses the token owner resolved via GET /user at startup (1 API call, cached for the run). Any login matching *[bot] is also treated as a bot regardless of token ownership.

Strategy detection (how to merge)

Per-PR, based on commit history (GET /repos/{repo}/pulls/{n}/commits):

  • Single commit → rebase (linear history, no merge commit)
  • Multiple commits, single author → squash (clean history)
  • Multiple commits, multiple authors → merge (preserves attribution)

Override with MERGE_STRATEGY=squash|rebase|merge.

Mechanism detection (when to fire)

Detected once per run via GET /repos/{repo}/branches/{base}/protection:

  • Required status checks configured → native auto-merge (gh pr merge --auto). GitHub queues the merge and fires it exactly when checks pass. Zero polling, no runner time consumed waiting.
  • No branch protection / no required checks → poll mergeable_state until clean, then merge directly. Polls every POLL_INTERVAL_SEC (default 30s) up to POLL_TIMEOUT_MIN (default 30min).

Override with MERGE_MECHANISM=native|poll.

Workflow trigger

auto-merge-prs.yml fires on:

  • workflow_run completion of Validate Config with conclusion == success (primary — fires immediately after CI passes on any PR)
  • Schedule every 2h at :55 (fallback for PRs already green before the workflow existed)
  • workflow_dispatch with optional pr_filter (comma-separated PR numbers)

Registered: tier 3 MEDIUM, min_quota: 300.

Architecture

The three-org chain

fork-sync-all is the control plane for a three-organisation mirror chain on GitHub, with a fourth leg into GitLab:

Interested-Deving-1896  ──►  OpenOS-Project-OSP
        ▲                           │
        │                           ▼
        │              OpenOS-Project-Ecosystem-OOC
        │                           │
        │                           ▼
        │                  GitLab openos-project
        │             (14 subgroups, 225 repos mirrored)
        │
        └──── upstream-commits / upstream-prs (OSP + OOC → I-D-1896)
OrgRole
Interested-Deving-1896Primary — forks live here, all automation runs here
OpenOS-Project-OSPSecondary mirror — receives pushes from I-D-1896
OpenOS-Project-Ecosystem-OOCTertiary mirror — receives pushes from OSP
gitlab.com/openos-projectGitLab mirror — receives pushes from OSP via GitLab CI

All automation runs in Interested-Deving-1896/fork-sync-all. The other orgs are passive recipients — they do not run their own automation except for the GitLab CI mirror job that pushes back to GitLab.


Data flow

Inbound (upstream → I-D-1896)

Three paths bring upstream changes into Interested-Deving-1896:

  1. sync-forks.yml (daily) — syncs all GitHub forks with their upstream parents
  2. sync-registered-imports.yml (daily at 04:55 UTC) — re-syncs repos registered in registered-imports.json, including non-GitHub sources (GitLab, Bitbucket, Codeberg, etc.)
  3. upstream-commits.yml / upstream-prs.yml (daily) — detects direct commits and open PRs in OSP/OOC that haven't been reflected upstream, and opens PRs in I-D-1896

Outbound (I-D-1896 → OSP → OOC → GitLab)

The mirror chain runs in sequence, each leg triggered by the previous:

mirror-to-osp.yml  ──►  mirror-osp-to-ooc.yml  ──►  GitLab CI (sync-to-gitlab.yml)
   (every 6h at :13)     (every 6h at :45)           (on OSP push)

flush-lifecycle.yml is the top-level entry point for a full pipeline run. It sets FLUSH_ACTIVE=true, holds a sentinel runner slot, and coordinates the three-stage sequence with quota reservation and pause/resume at reset windows:

flush-lifecycle.yml
  └─ pre-flush-prep.yml    ← cancels stale runs, merges PRs, validates config
  └─ full-chain-flush.yml  ← all mirror + README + CI stages in order
  └─ post-flush-prep.yml   ← integrity checks and queue health verification

full-chain-flush.yml orchestrates the pipeline stages themselves — mirror chain, README updates, sync, and validation — but should be triggered via flush-lifecycle.yml rather than directly, so the FLUSH_ACTIVE mutex and quota reservation are active for the full run.

GitLab subgroup placement

config/gitlab-subgroups.yml is the single source of truth for which repos go into which GitLab subgroup. The 14 subgroups map to topic areas:

SubgroupReposTopic
incus_deving49Incus / container infrastructure
yaml-tooling_deving34YAML, CI, and tooling
ops30Operations and control plane
agnostic-api_deving29Unified Agnostic API — virtual filesystems, AI/LLM adapters, OS-compat layers
penguins-eggs_deving17penguins-eggs ecosystem
linux-kernel_filesystem_deving14Kernel and filesystem
cachyos_deving12CachyOS packages
ai-agents_deving10AI agent tooling
accessibility_deving9Screen readers, Braille, WCAG auditing, audio overviews
git-management_deving9Git tooling
neon-deving8KDE Neon ecosystem
rust-systems_deving2Rust system tools
taubyte_deving1Taubyte platform
immutable-filesystem_deving1Immutable Linux

Repos not listed in any subgroup fall into the ops default subgroup.


Quota management

Both GH_TOKEN and SYNC_TOKEN belong to the same GitHub user and share a single 5000 req/hr REST bucket. The system has three layers of protection:

quota-reserve.yml  ──►  queue-manager.yml
  (every 30 min)          (every 30 min)

quota-monitor.yml is a separate manual-dispatch-only tool for waiting out quota exhaustion. It is not part of the automatic quota management loop — see Operations for when and how to use it.

LayerThresholdAction
quota-reserve< 1000 remainingCancels tier-4 (LOW) queued runs
quota-reserve< 500 remainingCancels tier-3 (MEDIUM) queued runs
queue-managerRun queued > 25 minEvicts stale queued runs
queue-managerDuplicate workflowKeeps newest, cancels older

Workflow priority tiers are defined in config/workflow-priority-tiers.yml. Tier 1 (CRITICAL) runs are never cancelled. See Operations for the full quota reference.


Config files

FilePurpose
config/gitlab-subgroups.ymlGitLab subgroup placement for 225 repos (14 subgroups)
config/ona-projects.ymlOna project registry — maps repos to project IDs, environment classes, and tags
config/workflow-priority-tiers.ymlPriority tier for each workflow (used by queue-manager and quota-reserve)
config/workflow-quota-costs.ymlmin_quota + cost tiers per workflow — source of truth for quota-reserve and pre-flight checks
config/workflow-cost-profiles.ymlDetailed REST/GraphQL/GitLab/AI call estimates per workflow (used by rate-limit-profile.sh)
config/workflow-sync.ymlGitHub ↔ GitLab CI job mapping (used by validate-workflow-guards)
config/ota-registry.ymlRepos opted in to the OTA update system
config/ota-blocklist.ymlOrgs/namespaces excluded from OTA by default
config/template-manifest.ymlTemplate sync profiles and file ownership
config/template-consumers.ymlRepos consuming each template profile
registered-imports.jsonUpstream repos registered for ongoing sync

vendor/

vendor/ contains third-party components that fork-sync-all hosts or deploys. It is distinct from scripts/ (first-party automation) and config/ (config data).

Current components:

ComponentDescription
vendor/infra-dashboardMirror-health and package-search SPA + Rust API backend

All vendored components must be deployment-agnostic — no distro names, org-specific URLs, or hardcoded deployment values. See Contributing for the enforcement workflow.


Token architecture

Two GitHub PATs are in active use, both owned by the same user (ID 202036334) and sharing the same 5000 req/hr quota:

SecretUsed byScope
SYNC_TOKENMost workflowsrepo, workflow, admin:org
GH_TOKENValidation, README, config workflowsrepo, workflow

GitLab operations use GITLAB_SYNC_TOKEN (api, read/write_repository scope).

Token expiry is monitored weekly by token-health.yml. See Token Rotation for rotation procedures.

Workflow Triggers

All workflows in .github/workflows/. Grouped by function, with every trigger listed.

Plain-text version: DOCS/workflow-triggers.txt
Published: interested-deving-1896.github.io/fork-sync-all/workflow-triggers.html
Auto-generated on 2026-07-03 from .github/workflows/ and config/workflow-quota-costs.yml


Index

Jump to any section:

Quick links: Glossary · Schedule Summary · Source

Accessibility

WorkflowSynopsisFileScheduleAlso triggers on
Check Accessibility ▶ RunMulti-layer accessibility audit — CODEOWNERS coverage, README screen-reader scan, WCAG 2.1 AA HTML check, audio overview (espeak-ng), and Braille output (liblouis). Commits README.audio.mp3 and README.brl artifacts.check-accessibility.ymlWeekly Mon 04:17push to README.md, .github/CODEOWNERS, CODEOWNERS (+1 more) · dispatch

AI & Cost Tracking

WorkflowSynopsisFileScheduleAlso triggers on
Eco Audit ▶ RunAudits fork-sync-all against KDE Eco / Blue Angel DE-UZ 215 criteria. Checks green hosting, CI efficiency, telemetry, dependency footprint. Stubs KEcoLab energy measurement for GitLab activation. Weekly on Sundays.eco-audit.ymlWeekly Sun 05:00push to scripts/eco/**, .github/workflows/eco-audit.yml, config/workflow-quota-costs.yml · dispatch
opencode ▶ RunOpenCode AI assistant integration. Triggered on issue/PR comments.opencode.yml
Sync Agent Prices ▶ RunWeekly hybrid A+B+C price refresh for config/agent-cost-profiles.yml. Fetches LiteLLM model_prices_and_context_window.json at a pinned SHA, diffs against current prices, and opens a PR for human review if anything changed. Flags stale manual entries as warnings. Never auto-merges.sync-agent-prices.ymlWeekly Mon 09:00dispatch
Track Agent Costs ▶ RunRecords AI agent session cost estimates (OCUs, USD, tokens) to a structured JSON log. Supports Ona Agent, Codex, GitHub Models, and direct API agents. Builds an observed cost dataset to replace code-audit estimates in DOCS/ai-agent-costs.md over time.track-agent-costs.ymldispatch

BDFS / Filesystem Workspace

WorkflowSynopsisFileScheduleAlso triggers on
BDFS Dev Workspace ▶ RunCreates and manages mutable dev workspaces on top of immutable filesystem roots using the bdfs framework (btrfs, overlay, or dwarfs backends). Actions: create, drop, list, commit, status.bdfs-dev.ymldispatch
BDFS Dev — BTRFS Backend ▶ RunCreates a writable BTRFS snapshot of a source subvolume as a bdfs dev workspace. Source must be on a BTRFS filesystem.bdfs-dev-btrfs.ymldispatch
BDFS Dev — DwarFS Backend ▶ RunMounts a DwarFS image read-only as the lower layer of an overlayfs workspace, with a writable upper layer (BTRFS subvolume or tmpfs).bdfs-dev-dwarfs.ymldispatch
BDFS Dev — Overlay Backend ▶ RunCreates an overlayfs workspace with a source path as the read-only lower layer and tmpfs or a directory as the writable upper layer. Works on any filesystem.bdfs-dev-overlay.ymldispatch
bdfs Package ▶ RunPackages fork-sync-all as a bdfs workspace (DwarFS + BTRFS).bdfs-package.ymlpush to (any) · dispatch

Bugzilla Integration

WorkflowSynopsisFileScheduleAlso triggers on
Sync to Bugzilla ▶ RunParses commits and PRs for Bug NNN references and updates Bugzilla status and comments.sync-to-bugzilla.ymlpull_request · dispatch

Build & Release

WorkflowSynopsisFileScheduleAlso triggers on
Build ▶ RunBuilds the project. Triggered on push/PR.build.ymlpush to (any) · pull_request · dispatch
Build (self-hosted) ▶ RunBuilds the project on a self-hosted runner.build-selfhosted.ymlpush to (any) · dispatch
Build ARM64 ▶ RunBuilds the project for ARM64 architecture.build-arm64.ymlpush to (any) · pull_request · dispatch
Build x86-64 ▶ RunBuilds the project for x86-64 architecture.build-x86.ymlpush to (any) · pull_request · dispatch
Update kde-builder vendor ▶ RunPulls latest kde-builder upstream into vendor/kde-builder/ via git subtree. Manual dispatch only.update-kde-builder-vendor.ymldispatch
Checks ▶ RunGeneral checks workflow. Triggered on push/PR.checks.ymlpush to (any) · pull_request
Mirror Releases ▶ RunMirrors GitHub Releases (tags + release notes + assets) from Interested-Deving-1896 repos to their OSP and OOC counterparts.mirror-releases.ymlEvery 12h at :03dispatch
OTA Release ▶ RunTriggered on semver tag push. Assembles and delivers OTA updates to all opted-in repos in config/ota-registry.yml, then updates CHANGELOG.md with release notes.ota-release.ymlpush to (any) · dispatch
Release ▶ RunCreates a GitHub release and uploads build artifacts on tag push.release.yamlpush to (any) · dispatch
DwarFS Pack Release ▶ RunPackages a DwarFS release artifact when an upstream release completes.dwarfs-pack-caller.ymlRelease completes · dispatch
Push Kernel Content ▶ RunPushes kernel version metadata (READY, VERSION, config/, patches/, README.md) to the debian-{arch}-kernel-base repos (one per arch, up to 10).push-kernel-content.ymldispatch
Seed Patchset Branches ▶ RunSeeds 9 patchset branches per debian-{arch}-kernel-base repo for Debian (trixie/forky/sid), Devuan (excalibur/forky/ceres), and Ubuntu (resolute/stonking/devel).seed-patchset-branches.ymldispatch
Generate architecture config ▶ RunGenerates architecture config from org repo metadata.gen-arch-config.ymldispatch

CI & Failure Resolution

WorkflowSynopsisFileScheduleAlso triggers on
Rate-Limit Re-trigger ▶ RunScans recently-failed workflow runs, identifies those that failed due to rate limiting, and re-triggers them after their quota reset epoch.rate-limit-rerun.ymlEvery 4h at :05dispatch
Notification Poller ▶ RunPolls GitHub notifications for unread CI failure notifications and triggers resolve-failures immediately when any are found.notify-poller.ymlEvery 4h at :32dispatch
Resolve CI Failures ▶ RunAnalyses CI failure patterns across OSP-bound repos and applies automated fixes (dependency updates, config corrections, workflow patches) where possible.resolve-failures.ymlDaily 07:43dispatch
Rebuild LTS Branch (penguins-eggs) ▶ RunRebases the all-features branch onto the upstream master after each pieroproietti sync, then force-pushes the result to the lts branch.rebase-lts.ymlSync pieroproietti Forks completes · dispatch
Rate Limit Status ▶ RunQueries current rate limit status for all external APIs used by fork-sync-all. On-demand health check.rate-limit-status.ymlRate-Limit Re-trigger completes · dispatch
Notification Manager ▶ RunHourly notification triage. Auto-marks known-safe patterns (mirror failures, quota artifacts, Dependabot) as read. Supports manual dispatch with list/mark-all-read actions.notify-manager.yml17 * * * *Resolve CI Failures completes · dispatch
Runner Status ▶ RunReports runner utilisation and queue depth across the org. Flags workflows with queue depth above configurable warn/critical thresholds.runner-status.ymlEvery 1h at :10Queue Manager completes · Rate-Limit Re-trigger completes · dispatch

Documentation & Publishing

WorkflowSynopsisFileScheduleAlso triggers on
Deploy Book ▶ RunBuilds the mdBook documentation site from DOCS/ and deploys it to GitHub Pages at interested-deving-1896.github.io/fork-sync-all/.deploy-book.ymlpush to DOCS/**, book.toml, README.md (+4 more) · dispatch
Generate Book Pages ▶ RunRegenerates DOCS/generated/ pages from config sources (workflow-quota-costs.yml, priority-tiers.yml, gitlab-subgroups.yml, registered-imports.json) and commits the result.generate-book-pages.ymlpush to config/workflow-quota-costs.yml, config/workflow-priority-tiers.yml, config/gitlab-subgroups.yml (+3 more) · dispatch
Update Book Index ▶ RunRegenerates DOCS/generated/ pages (source tree, glossary, workflow index) on push to main. Commits with [skip ci].update-book-index.ymlpush to .github/workflows/**, config/workflow-quota-costs.yml, config/workflow-priority-tiers.yml (+8 more) · dispatch
Sync penguins-eggs docs to penguins-eggs-book ▶ RunTriggered by repository_dispatch from penguins-eggs when docs/chromiumos/ changes on all-features. Syncs the updated docs into the penguins-eggs-book repo.sync-eggs-docs-to-book.ymldispatch
Export Book (Multi-Engine) ▶ RunExports the book to one or all supported engines (mdBook, MkDocs, Docusaurus, Pandoc). Manual dispatch only.book-export.ymldispatch
GitBook OSS ▶ RunManages the GitBook OSS (Next.js) renderer. Actions: build, export, update, dev-info. Weekly update check on Mondays.gitbook-oss.ymlWeekly Mon 04:17dispatch
Translate Docs ▶ RunTranslates DOCS/ mdBook pages into a target language using GitHub Models API. Writes translated files to DOCS// and upserts a language section in SUMMARY.md.translate-docs.yml15 11 */2 * *Deploy Book completes · dispatch
Generate NotebookLM Content ▶ RunGenerates NotebookLM content artifacts (audio, video, slides, infographic, quiz, flashcards, report) for a given notebook and uploads them to a GitHub Release.generate-notebooklm.ymldispatch
Refresh NotebookLM Auth ▶ RunRotates the short-lived __Secure-1PSIDTS cookie in NOTEBOOKLM_AUTH_JSON weekly and writes the updated state back to the repo secret.refresh-notebooklm-auth.ymlWeekly Tue 06:17dispatch
Update Workflow Triggers Doc ▶ RunRegenerates docs/workflow-triggers.md and docs/workflow-triggers.txt whenever a workflow file changes on main. Commits the result directly to main.update-workflow-triggers-doc.ymlpush to .github/workflows/**, config/workflow-quota-costs.yml · dispatch
Upload NotebookLM Assets ▶ RunUploads NotebookLM generated output files (audio, PDF) to a GitHub Release. Creates the release if it does not exist yet.upload-notebooklm.ymldispatch

Fork & Import Sync

WorkflowSynopsisFileScheduleAlso triggers on
Sync All Forks ▶ RunSyncs all branches of every fork owned by Interested-Deving-1896 with their upstream via the GitHub merge-upstream API, falling back to force-reset on divergence.sync-forks.ymlDaily 06:07dispatch
Sync Registered Imports ▶ RunRe-syncs all repos listed in registered-imports.json — bare-clones each source URL and pushes all branches and tags to Interested-Deving-1896.sync-registered-imports.ymlDaily 04:55dispatch
Sync FSA Forks ▶ RunKeeps downstream fork-sync-all forks in sync with upstream. Opens PRs on drift.sync-fsa-forks.ymlDaily 04:00push to (any) · dispatch
Sync UAA Vendor ▶ RunSyncs vendor/unified-agnostic-api from Interested-Deving-1896/unified-agnostic-api via sparse checkout. Runs on push to vendor/unified-agnostic-api/** or weekly schedule.sync-uaa-vendor.ymlWeekly Tue 05:00push to vendor/unified-agnostic-api/**, fsa-api/uaa/**, .github/workflows/sync-uaa-vendor.yml · dispatch
Sync Shell Tools Vendor ▶ RunSparse-clones each of the 24 shell-tools forks and copies entrypoint scripts into vendor/shell-tools/. One clone per tool (~2 REST calls each via git protocol). Weekly Sunday 02:00 UTC.sync-shell-tools.ymlWeekly Sun 02:00dispatch
Integrate Shell Tools ▶ RunRuns smoke tests and integration demos for vendored shell-tools. No GitHub API calls — pure runner execution. Weekly Sunday 03:00 UTC (after sync-shell-tools).integrate-shell-tools.ymlWeekly Sun 03:00Sync Shell Tools Vendor completes · dispatch
Upstream Direct Commits from OSP + OOC ▶ RunDetects commits pushed directly to OSP/OOC default branches (without a PR) and opens PRs against Interested-Deving-1896 to reconcile them.upstream-commits.ymlDaily 03:47Mirror Interested-Deving-1896 → OSP completes · dispatch
Upstream PRs from OSP + OOC ▶ RunDetects commits on OSP and OOC default branches that are not present in Interested-Deving-1896 and opens PRs to bring them upstream.upstream-prs.ymlDaily 03:33Mirror Interested-Deving-1896 → OSP completes · dispatch
Import Repository ▶ RunPlatform-agnostic repo importer — clones any public or authenticated git URL into Interested-Deving-1896, optionally mirrors through the OSP→OOC chain and registers for ongoing sync.import-repo.ymldispatch
Sync KDE Groups Mirrors ▶ RunSyncs all KDE group mirror repos under openos-project/kde-ecosystem-deving/kde-groups from invent.kde.org. Daily schedule.sync-kde-groups-mirrors.ymlDaily 01:00dispatch
Sync KDE Neon Mirrors ▶ RunSyncs all KDE Neon mirror repos in openos-project/kde-ecosystem-deving/neon-deving from invent.kde.org/neon/. Daily schedule, offset 30 min from Sync KDE Groups Mirrors.sync-kde-neon-mirrors.ymlDaily 01:30dispatch
Sync Ona Projects ▶ RunReconciles config/ona-projects.yml with the Ona API. Creates or updates Ona projects for all repos in the org chain. Runs in dry-run mode when ONA_TOKEN is absent.sync-ona-projects.ymlDaily 06:00push to config/ona-projects.yml · dispatch
Sync Pieroproietti GitLab Forks ▶ RunSyncs the three pieroproietti GitLab forks (penguins-eggs, penguins-eggs-book, oa-tools) from their GitHub upstreams. Mirrors branches, tags, and creates GitLab Releases for new tags.sync-pieroproietti-gl-forks.ymlDaily 02:15dispatch
Sync Registry Backend ▶ RunAgnostic registry sync backend propagated to upstream-sync consumers. Dispatch-only, no schedule, no hardcoded defaults. Reads vars.AF_REGISTRY_REPO / AF_REGISTRY_BRANCH / AF_REGISTRY_PATH for self-configuration.sync-registry-backend.ymldispatch
Sync Registry Sources ▶ RunRegistry-driven upstream sync (central orchestrator) — reads a JSON registry of upstream sources and syncs each repo via merge-upstream or force-reset. Runs daily from fork-sync-all with penguins-eggs defaults.sync-registry-sources.ymlDaily 03:05Sync Registered Imports completes · dispatch
Sync Upstream Mirrors (GitLab) ▶ RunSyncs all upstream mirror repos in openos-project/upstream-mirrors from their original GitHub sources. Daily schedule.sync-upstream-mirrors.ymlDaily 00:00dispatch
Sync Upstream Sources ▶ RunReads the Origins section of every OSP-bound repo and syncs each referenced external fork to its upstream HEAD via merge-upstream or force-reset.sync-upstream-sources.ymlDaily 01:37dispatch
Sync btrfs-devel Branches ▶ RunSyncs tracked btrfs-devel branches from the upstream kernel tree into the btrfs-dwarfs-framework fork.sync-btrfs-devel-branches.ymlDaily 05:02dispatch
Sync pieroproietti Forks ▶ RunSyncs all penguins-eggs forks owned by Interested-Deving-1896 with their upstream pieroproietti sources via merge-upstream.sync-pieroproietti-forks.ymlDaily 01:07dispatch
Sync-in ▶ RunManages Sync-in server/client lifecycle. Server role: health-check, deploy, token rotation. Client role: register OSP-bound repos as workspaces, trigger syncs. Scheduled health every 6h, workspace sync daily.sync-in.ymlEvery 6h at :37 · Daily 10:15dispatch
Upstream Contribute (caller) ▶ RunConsumer-repo caller for upstream-contribute.yml. Analyses push diff and opens upstream PRs.upstream-contribute-caller.ymlpush to (any) · dispatch
Upstream Workflow Proposal ▶ RunScans OSP-bound repos for new workflow patterns not present in fork-sync-all and opens a PR proposing them as template skeletons.upstream-workflow-proposal.ymlWeekly Mon 06:06dispatch
btrfs-devel sync ▶ RunWeekly sync of fs/btrfs/ subtree from kdave/btrfs-devel into this repo via git read-tree. Opens a PR when changes are found.btrfs-devel-sync.ymlWeekly Mon 03:00dispatch

Full Pipeline

WorkflowSynopsisFileScheduleAlso triggers on
Flush Lifecycle Manager ▶ RunCoordinates the three-stage flush pipeline with quota reservation, runner slot holding via a parallel sentinel job, and pause/resume at quota reset windows. Sets FLUSH_ACTIVE=true so queue-manager and quota-reserve protect flush stages.flush-lifecycle.ymlWeekly Sun 06:00Pre-Flush Prep completes · dispatch
Pre-Flush Prep ▶ RunPrepares the system for a clean full-chain-flush — cancels stale runs, merges ready PRs, validates config, cleans merged branches, removes template pollution, then dispatches full-chain-flush when quota is sufficient.pre-flush-prep.ymldispatch
Full Chain Flush ▶ RunOrchestrates the complete mirror chain in sequence — mirror-to-osp → mirror-osp-to-ooc → mirror-osp-to-gitlab — with quota checks between each stage.full-chain-flush.ymlMonthly 1st 05:17dispatch
Post-Flush Verification ▶ RunEnd-to-end health check after full-chain-flush — mirror integrity across all three pairs, CI status on I-D-1896 OSP-bound repos, quota health, and workflow queue health.post-flush-prep.ymlFull Chain Flush completes · dispatch
Critical Deploy ▶ RunFast-lane workflow for deploying critical fixes when the system is degraded — commits and pushes changes, clears the queue aggressively, then dispatches priority workflows.critical-deploy.ymldispatch
Critical Deploy — All ▶ RunFast-lane critical deploy across all four platforms (Interested-Deving-1896, OSP, OOC, GitLab) in sequence. Cost is approximately 4× the single-org variant.critical-deploy-all.ymldispatch
Critical Deploy — OOC ▶ RunFast-lane critical deploy scoped to OpenOS-Project-Ecosystem-OOC — same three-phase pattern as Critical Deploy but targets the OOC mirror org only.critical-deploy-github-ooc.ymldispatch
Critical Deploy — OSP ▶ RunFast-lane critical deploy scoped to OpenOS-Project-OSP — same three-phase pattern as Critical Deploy but targets the OSP mirror org only.critical-deploy-github-osp.ymldispatch
Critical Deploy — Stub (template — not functional) ▶ RunTemplate for new platform critical deploy targets. Non-functional until copied, renamed, and filled in. Update costs when the platform is activated.critical-deploy-stub.ymldispatch
GitLab Critical Deploy ▶ RunFast-lane GitLab mirror recovery. Pushes current HEAD directly to GitLab via HTTPS, cancels pending pipelines, pauses/resumes schedules, and optionally triggers a fresh pipeline. Works even when GitHub quota is near 0.critical-deploy-gitlab.ymldispatch
Flush Active Watchdog ▶ RunClears FLUSH_ACTIVE=false whenever Flush Lifecycle Manager or any critical-deploy workflow completes. Prevents stuck-mutex after force-cancel.flush-active-watchdog.ymlFlush Lifecycle Manager completes · Full Chain Flush completes · Critical Deploy completes · Critical Deploy — All completes · Critical Deploy — OSP completes · Critical Deploy — OOC completes · GitLab Critical Deploy completes · dispatch
Pipeline Telemetry ▶ RunPost-run observability workflow. Fetches completed run data, builds a span tree (workflow→jobs→steps), computes Thoth-equivalent metrics, parses log severity, writes a step summary and trace artifact, and upserts a rolling metrics issue.pipeline-telemetry.ymlFull Chain Flush completes · Pre-Flush Prep completes · Mirror Interested-Deving-1896 → OSP completes · Mirror OSP → GitLab completes · Mirror to OpenOS-Project-Ecosystem-OOC completes · Reconcile Org References completes · Check CI Status completes · Sync All Forks completes · Sync Registered Imports completes · Pre-Mirror CI Gate completes · Verify Mirror Integrity completes · Post-Flush Verification completes · dispatch
Bootstrap Triggers ▶ RunOne-shot self-destruct workflow that fires pending workflow_dispatch triggers on push.bootstrap-triggers.ymlpush to .github/workflows/bootstrap-triggers.yml · dispatch

Git Platform Sync

WorkflowSynopsisFileScheduleAlso triggers on
Check GitLab CI Sync ▶ RunCompares paired jobs in .gitlab-ci.yml against config/workflow-sync.yml and reports drift — scripts with changed entry points, mismatched cadence rules, or jobs missing from either side.check-gitlab-sync.ymlValidate Config completes · dispatch
Git Platform Sync ▶ RunAgnostic git platform sync. Replaces sync-to-gitlab.yml (direction=push) and sync-from-gitlab.yml (direction=pull). Supports GitHub, GitLab, Gitea, Forgejo, Codeberg as source or destination.git-platform-sync.ymlDaily 09:23 · Daily 04:27Add Mirror Repo completes · dispatch
Sync from GitLab ▶ RunDEPRECATED. Superseded by Git Platform Sync (direction=pull). Stub kept for backwards compatibility.sync-from-gitlab.ymldispatch
Sync to GitLab Variant ▶ RunVariant of Sync to GitLab that uses a different token and push strategy — used when the primary sync is blocked or for testing.sync-to-gitlab-variant.ymlDaily 01:50push to config/ota-registry.yml, config/ota-blocklist.yml, .ota/schema.yml (+2 more) · dispatch
Sync to GitLab ▶ RunDEPRECATED. Superseded by Git Platform Sync (direction=push). Stub kept for backwards compatibility.sync-to-gitlab.ymldispatch

Infrastructure & Environment

WorkflowSynopsisFileScheduleAlso triggers on
Devcontainer SDK ▶ RunValidates devcontainer.json, features, and automations templates. Optionally builds and pushes the devcontainer image or publishes features to GHCR.devcontainer-sdk.ymlpush to .devcontainer/**, .github/workflows/devcontainer-sdk.yml · dispatch
Docker → Incus Migration ▶ RunScans repos for Docker artifacts (Dockerfile, docker-compose.yml) and replaces them with Incus equivalents. Runs after Add Mirror Repo and weekly.docker-to-incus.ymlWeekly Sun 03:08Add Mirror Repo completes · dispatch
FSA API ▶ RunFSA API server lifecycle and adapter dispatch. Validates config, smoke-tests server startup, or calls individual adapters directly via workflow_dispatch.fsa-api.ymldispatch
Test Time Format ▶ RunValidates time_format.py portability across glibc, musl, and BSD libc. Runs on push/PR to time_format.py.test-time-format.ymlpush to scripts/includes/time_format.py, .github/workflows/test-time-format.yml · pull_request · dispatch

Maintenance & Housekeeping

WorkflowSynopsisFileScheduleAlso triggers on
Reconcile Identity Assets ▶ RunDetects the current FSA instance, selects the matching brand variant, writes active assets to assets/brand/.active/, and injects identity content into DOCS/cover.md.reconcile-identity-assets.ymlpush to assets/brand/**, config/identity-assets.yml, DOCS/cover.md · Mirror Interested-Deving-1896 → OSP completes · Mirror OSP → GitLab completes · dispatch
Cleanup Stale Branches ▶ RunDeletes branches that have been merged into the default branch across all repos in Interested-Deving-1896, OSP, and OOC.cleanup-branches.ymlMonthly 1st 04:29Sync All Forks completes · dispatch
Validate Config ▶ RunValidates all config files (gitlab-subgroups.yml, workflow-sync.yml, priority-tiers.yml, registered-imports.json) on every push that touches them. Blocks merges on invalid config.validate-config.ymlpush to config/gitlab-subgroups.yml, config/workflow-sync.yml, config/workflow-cost-profiles.yml (+16 more) · pull_request · dispatch
Reconcile Org References ▶ RunRewrites org/repo references in OSP and OOC mirrors to point at the correct org, fixing stale Interested-Deving-1896 references left by the mirror process.reconcile-org-refs.yml50 5 */2 * *dispatch
Cleanup Template Pollution ▶ RunRemoves files incorrectly propagated from fork-sync-all to consumer repos via the template sync pipeline, across all three GitHub orgs and GitLab.cleanup-pollution.ymlSync Template completes · dispatch
Sync Template ▶ RunSyncs fork-sync-all's file tree into target repos. Three modes — create (new repo + mirror chain), inject (copy into existing repo), propagate (push-triggered sync to all consumers in template-consumers.yml).sync-template.ymlpush to .devcontainer/**, .ona/**, config/template-manifest.yml · dispatch
Update Infrastructure Dependencies ▶ RunScans workflow files across the three-org chain for outdated Actions versions, EOL runners, and EOL Node/Python versions, then opens PRs.update-infra-deps.ymlWeekly Mon 06:11dispatch
Generate OSP Dependency Graph ▶ RunScans all OSP-bound repos for package.json and requirements.txt files and generates a dependency graph showing inter-repo relationships.generate-dep-graph.ymlWeekly Sun 03:10Sync Registered Imports completes · dispatch
Token Health Monitor ▶ RunChecks expiry dates for all tracked PATs and GitLab tokens. Opens a GitHub issue labelled token-monitor when any token expires within 45 days.token-health.ymlWeekly Mon 09:24dispatch
Rotate Secret Token ▶ RunRotates GitHub PATs and GitLab tokens stored as org/repo secrets. Validates the new token before committing, then triggers Cancel Runs After Token Rotation to clear stale runs.rotate-token.ymldispatch
Cancel Runs After Token Rotation ▶ RunCancels any queued or in-progress workflow runs immediately after token rotation to prevent runs using the old token.cancel-post-rotation.ymlRotate Secret Token completes · dispatch
Branch Hygiene Report ▶ RunReports stale and unmerged branches. Manual dispatch only.branch-hygiene-report.ymlWeekly Mon 14:00dispatch
Manage Subtrees ▶ RunKeeps git subtrees, submodules, and umbrella repo relationships current per config/subtree-manifest.yml.manage-subtrees.ymlWeekly Sun 01:00dispatch
Org Storage Maintenance ▶ RunWeekly GitLab storage housekeeping across openos-project: triggers artifact expiry and deletes old generic package versions older than 90 days (keeps 5 per package).org-storage-maintenance.ymlWeekly Sun 02:00dispatch
Pin Manager ▶ RunManages version pinning, GitHub profile pins, and repo issue pins.pin-manager.ymlWeekly Mon 06:00 · Daily 07:00dispatch

Mirror Chain

WorkflowSynopsisFileScheduleAlso triggers on
Mirror Interested-Deving-1896 → OSP ▶ RunBare-clones every repo in Interested-Deving-1896 and git push --mirror into OpenOS-Project-OSP, syncing all branches, tags, and refs exactly.mirror-to-osp.ymlEvery 6h at :13dispatch
Mirror to OpenOS-Project-Ecosystem-OOC ▶ RunBare-clones every repo in OpenOS-Project-OSP and git push --mirror into OpenOS-Project-Ecosystem-OOC, completing the second hop of the three-org mirror chain.mirror-osp-to-ooc.yaml15 * * * *push to (any) · dispatch
Mirror to OpenOS-Project-Ecosystem-OOC ▶ RunBare-clones every repo in OpenOS-Project-OSP and git push --mirror into OpenOS-Project-Ecosystem-OOC, completing the second hop of the three-org mirror chain.mirror-osp-to-ooc.ymlEvery 6h at :45dispatch
Mirror OSP → GitLab ▶ RunMirrors every repo in OpenOS-Project-OSP to its GitLab counterpart under openos-project, creating the GitLab project in the correct subgroup if it does not exist yet.mirror-osp-to-gitlab.ymlDaily 01:23Add Mirror Repo completes · dispatch
Mirror Orgs ▶ RunMirrors all repos from Interested-Deving-1896 to OpenOS-Project-OSP and OpenOS-Project-Ecosystem-OOC using bare clone + push --mirror.mirror-orgs-full.ymlDaily 02:17dispatch
Mirror Watchdog ▶ RunTriggers when any mirror workflow fails — waits 5 minutes then retries once. Surfaces persistent failures in the Actions tab without consuming quota on repeated retries.mirror-orgs-watchdog.ymlMirror Interested-Deving-1896 → OSP completes · Mirror Orgs completes · Mirror OSP → GitLab completes · Mirror Releases completes · Mirror Artifacts completes · dispatch
Mirror Artifacts ▶ RunMirrors GitHub Releases, Flatpak packages, and RPM packages from Interested-Deving-1896 repos to their OSP and OOC counterparts.mirror-artifacts.ymlDaily 02:10dispatch
Mirror Chain Dispatch ▶ RunAgnostic mirror-chain backend. Dispatch-only on canonical instance — dedicated mirror workflows own schedules. Downstream forks without dedicated workflows may add a schedule.mirror-chain-dispatch.ymldispatch
Verify Fork Integrity ▶ RunCompares this repo's default-branch HEAD against its upstream parent (or upstream_override from .ota/config.yml). Reports sync status; configurable hard-fail on drift.verify-fork-integrity.ymlWeekly Mon 06:25Sync All Forks completes · dispatch
Verify Mirror Integrity ▶ RunCompares default-branch HEAD SHAs between source and destination for all OSP-bound repos after a mirror stage. Reports mismatches as warnings; configurable hard-fail mode.verify-mirror-integrity.ymlMirror Interested-Deving-1896 → OSP completes · Mirror to OpenOS-Project-Ecosystem-OOC completes · Mirror OSP → GitLab completes · dispatch
Mirror Flatpak Repo ▶ RunBuilds and publishes a self-hosted Flatpak repo on GitHub Pages. Downloads Flatpak bundles from OSP/OOC releases and imports them into the org flatpak-repo.mirror-flatpak.ymlDaily 05:00dispatch
Mirror GHCR Images ▶ RunRe-tags and pushes GHCR container images from an upstream owner into OSP and OOC orgs. Daily schedule.mirror-ghcr.ymlDaily 03:00dispatch
Mirror PyPI Packages ▶ RunRe-publishes PyPI packages from upstream repos to OSP/OOC with org-prefixed package names (e.g. osp-linux-kernel-manager).mirror-pypi.ymldispatch
Mirror RPM Repo ▶ RunMirrors RPM packages from OSP/OOC releases to a self-hosted RPM repo on GitHub Pages. Daily schedule.mirror-rpm.ymlDaily 04:30dispatch
Mirror to OpenOS-Project-OSP ▶ RunMirrors Interested-Deving-1896 repos to OpenOS-Project-OSP on schedule and push.mirror.yaml0 * * * *push to (any) · dispatch

OSP-Bound Repo Management

WorkflowSynopsisFileScheduleAlso triggers on
Manage Repo Settings ▶ RunDeclarative repo settings drift detection and enforcement. Check mode reads current state (1 REST call per repo) and reports drift. Apply mode patches drifted fields (1-3 REST calls per drifted repo).manage-repo-settings.ymlWeekly Mon 04:30dispatch
Add Mirror Repo ▶ RunAdds a new repo to the three-org mirror chain (Interested-Deving-1896 → OSP → OOC) by creating the repo in each org, setting up webhooks, and registering it in gitlab-subgroups.yml.add-mirror-repo.ymldispatch
Create OOC GitLab Subgroups ▶ RunCreates the GitLab subgroup structure for OpenOS-Project-Ecosystem-OOC and records the resulting subgroup IDs.create-ooc-subgroups.ymldispatch
Delete Stale Repos ▶ RunOne-shot cleanup of superseded repos across GitHub orgs and GitLab. Manual dispatch only.delete-stale-repos.ymldispatch
Onboard Repository ▶ RunOnboards new repos into the ecosystem — applies labels, branch protection, topics, description, welcome issue, and dispatches sync-template/setup-osp-mirrors/sync-registered-imports.onboard-repo.ymlpush to registered-imports.json, config/template-consumers.yml · dispatch
Provision GitLab Maintenance Schedules ▶ RunPushes .gitlab/scheduled-maintenance.yml and creates a weekly maintenance schedule on every actively developed project under openos-project. Safe to re-run.provision-maintenance.ymldispatch
Setup OSP Mirror Workflows ▶ RunEnsures all repos in OpenOS-Project-OSP have the correct mirror workflow files and secrets configured for the OSP→OOC mirror chain.setup-osp-mirrors.ymlDaily 02:45Mirror Interested-Deving-1896 → OSP completes · dispatch

OTA System

WorkflowSynopsisFileScheduleAlso triggers on
OTA Reconcile ▶ RunWeekly drift detection and quota-fallback reconcile for mirror-chain consumer repos. Autonomously selects path A (stamp), B (drift PR), or C (quota-recovery PR) per repo based on .ota/version SHA, open PR state, and OTA_SYNC_INCOMPLETE variable.ota-reconcile.ymlWeekly Wed 03:17dispatch
OTA Self-Update ▶ RunPropagated to opted-in forks. Pulls the latest OTA release from fork-sync-all and applies it to the fork's workflow files.ota-self-update.ymlWeekly Mon 05:15dispatch
OTA Discover ▶ RunScans forks of fork-sync-all for .ota/config.yml with enabled: true and adds newly discovered repos to config/ota-registry.yml.ota-discover.ymlDaily 06:38dispatch
OTA Opt-In ▶ RunPropagated to opted-in forks. Fork owners run this once to create .ota/config.yml and open a registration PR against fork-sync-all's OTA registry.ota-opt-in.ymldispatch

PR Governance & Trust

WorkflowSynopsisFileScheduleAlso triggers on
Vouch Check PR ▶ RunHybrid A/B/C PR trust gate. Reads VOUCHED.td and changed file paths to select response — denounced authors auto-closed, unknown authors touching sensitive paths blocked, unknown authors on safe paths warned only.vouch-check-pr.yml
Vouch Manage ▶ RunManages contributor vouch status via issue/PR comments. Maintainers use vouch/unvouch/denounce commands; changes are applied via auto-opened PRs against VOUCHED.td.vouch-manage.ymldispatch
Vouch Sync Codeowners ▶ RunWeekly sync of CODEOWNERS entries and org members into VOUCHED.td via vouch-seed.sh. Opens a PR if VOUCHED.td changed.vouch-sync-codeowners.ymlWeekly Mon 04:23dispatch
Accessibility PR Gate ▶ RunAccessibility gate on pull requests. Blocks merge if accessibility violations are found.a11y-pr-gate.ymlpull_request
PR Gate ▶ RunRequired status check for incoming PRs. Checks quota remaining and posts a comment if the system is degraded. Two rate_limit calls per run.pr-gate.ymlpull_request
PR Lifecycle Guard ▶ RunReusable quota + queue pre-flight called by PR-creating workflows (OTA Release, Upstream PRs, Rebase PRs). One rate_limit call plus optional queue-manager pass.pr-lifecycle-guard.yml
PR Automation ▶ RunApplies size labels, path-based labels, reviewer auto-assignment, risky pattern detection, and auto-merge for low-risk PRs on every PR open or update.pr-automation.ymlpull_request
Auto-merge PRs ▶ RunMerges open PRs once required checks pass. Hybrid auto-detection per PR: scope (label/bot/all), strategy (rebase/squash/merge), mechanism (native auto-merge vs poll).auto-merge-prs.ymlEvery 6h at :55Validate Config completes · dispatch
Merge Ready PRs ▶ RunWaits for CI then merges all open PRs with passing checks across fork-sync-all and btrfs-dwarfs-framework.merge-ready-prs.ymldispatch
Rebase PRs ▶ RunRebases open PRs in Interested-Deving-1896 onto their base branch when they fall behind, keeping PRs mergeable without manual intervention.rebase-prs.yml10 5 */2 * *Validate Config completes · dispatch

Quota & Queue Management

WorkflowSynopsisFileScheduleAlso triggers on
Quota Reserve ▶ RunCancels low-priority queued runs when remaining quota drops below RESERVE_FLOOR (default 1000). Uses per-workflow min_quota from workflow-quota-costs.yml for cost-aware cancellation.quota-reserve.ymlEvery 30 mindispatch
Queue Manager ▶ RunDeduplicates queued workflow runs (keeps newest per workflow) and evicts runs queued longer than STALE_QUEUE_MIN (default 25 min) to prevent quota exhaustion cascades.queue-manager.ymlEvery 30 minRate-Limit Re-trigger completes · dispatch
Quota Monitor ▶ RunPolls GitHub quota and optionally dispatches a target workflow once quota recovers above a configurable threshold. Dispatch-only — never scheduled.quota-monitor.ymlRate-Limit Re-trigger completes · dispatch
Update Quota Cost Registry ▶ RunReads quota-instrument records from job logs, computes observed p50/p95 REST costs per workflow, and commits updated values to workflow-quota-costs.yml weekly.update-quota-costs.ymlWeekly Mon 08:00Pipeline Telemetry completes · dispatch
List Active Runs ▶ RunLists all active workflow runs with clickable web and API URLs.list-active-runs.ymlEvery 30 mindispatch

README Management

WorkflowSynopsisFileScheduleAlso triggers on
Create Missing READMEs ▶ RunCreates README.md from the standard template for OSP-bound repos that have no README, with placeholder sections for human-owned content.create-readmes.ymlDaily 07:08Add Mirror Repo completes · Import Repository completes · Clone Org completes · Merge Repos into Monorepo completes · dispatch
Update READMEs ▶ RunRegenerates AI-owned sections (what-it-does, architecture, ci, mirror-chain, etc.) in README.md for all OSP-bound repos, preserving human-owned sections.update-readmes.ymlDaily 03:15push to config/gitlab-subgroups.yml, config/template-manifest.yml · Sync Registered Imports completes · dispatch
Validate README Render ▶ RunChecks README.md for rendering issues — leaked log lines, unclosed fences, bare brackets, raw angle brackets, unclosed AI markers, missing H1, and empty sections.validate-readme-render.ymlpush to README.md · Update READMEs completes · dispatch
Inject Built-with-Ona Badges ▶ RunAdds a Built-with-Ona badge to README.md for all repos in Interested-Deving-1896 that are missing it. Skips repos that already have the badge.inject-badges.yml15 8 */2 * *Mirror OSP → GitLab completes · dispatch
LTS README Standardisation ▶ RunStandardises README.md structure for LTS-tagged repos, ensuring they follow the LTS template with correct version badges and support tables.lts-readmes.ymlMonthly 1st 03:19Rebuild LTS Branch (penguins-eggs) completes · dispatch
Inject Repo Motto ▶ RunInjects repo motto/slogan into README.md files across all orgs.inject-motto.yml30 8 */2 * *dispatch
Generate Repo Descriptions ▶ RunAI-powered per-file description generator. Fetches file tree (1 REST call) then reads each file for context (1 REST call per file) before calling GitHub Models. Cost scales with MAX_FILES setting.generate-repo-descriptions.ymlWeekly Sun 03:30dispatch
Translate READMEs ▶ RunTranslates README.md files for OSP-bound repos into additional languages using GitHub Models API. Writes translated files alongside the English original.translate-readmes.yml43 10 */2 * *Update READMEs completes · Add Mirror Repo completes · Import Repository completes · dispatch
README Wizard ▶ RunAI-guided README authoring — writes or rewrites a README for a specific repo according to custom instructions (audience, tone, sections), respecting existing human-owned markers.readme-wizard.ymldispatch
Trigger README Update (All Repos) ▶ RunDispatches update-readmes.yml for all OSP-bound repos in batch. Use after a rate-limit reset to propagate README updates org-wide.trigger-readme-update.ymldispatch

Security & Compliance

WorkflowSynopsisFileScheduleAlso triggers on
Audit Arch Repos ▶ RunWeekly audit of expected vs actual repos across Interested-Deving-1896. Reports missing, unexpected, and mismatched repos to the step summary.audit-arch-repos.ymlWeekly Mon 04:00dispatch
CodeQL ▶ RunCodeQL security analysis. Triggered on push/PR/schedule.codeql-analysis.ymlWeekly Mon 10:34push to (any) · pull_request · dispatch
Enforce Agnostic Vendor ▶ RunScans vendor/ for distro-specific hardcoded fallback values in shell, YAML, and TypeScript. All vendored components must be deployment-agnostic.enforce-agnostic-vendor.ymlpush to vendor/**, scripts/check-vendor-agnostic.sh, .github/workflows/enforce-agnostic-vendor.yml · pull_request · dispatch
Full Audit ▶ RunWeekly structural audit of workflows, scripts, config registries, assets, and vendor dirs. No REST calls.full-audit.ymlWeekly Mon 04:00dispatch
Generate SBOM ▶ RunFour-stage SBOM pipeline — Trivy generates CycloneDX+SPDX, sbomasm augments metadata, parlay enriches components, sbomqs scores quality. Runs weekly and on push to main. Release assets attached by OTA Release.generate-sbom.ymlWeekly Tue 02:41push to **.sh, **.py, **.yml (+4 more) · dispatch
Pin Workflow Actions ▶ RunPins GitHub Actions uses references to exact SHA commits via ratchet.pin-workflows.ymlWeekly Tue 05:00dispatch

Utility / On-Demand

WorkflowSynopsisFileTrigger
Bootstrap Org ▶ RunOne-shot org bootstrap: fork fork-sync-all into a new org, substitute config, set secrets, dispatch post-bootstrap workflows.bootstrap-org.ymldispatch
Cancel Stale Runs ▶ RunCancels queued and in-progress workflow runs older than MAX_AGE_MINUTES (default 90) or created before a fix commit, preventing stale runs from burning quota.cancel-stale-runs.ymlRate-Limit Re-trigger completes · dispatch
Check CI Status ▶ RunAgnostic CI status checker. Runs check-ci.sh for each enabled target in config/ci-check-targets.yml (GitHub orgs and GitLab groups).check-ci.ymlAdd Mirror Repo completes · dispatch
Check OOC CI Status ▶ RunDaily check of CI status on the default branch HEAD for every OOC-bound repo. Reports failing repos to the step summary.check-ooc-ci.ymldispatch
Check Shell Tools CI ▶ RunBatch-fetches CI run status for all 24 shell-tools repos via a single GraphQL query. Minimal quota cost. Weekly Monday 06:30 UTC.check-shell-tools-ci.ymlSync Shell Tools Vendor completes · dispatch
CI ▶ RunRuns CI checks on push and pull request events.ci.yamlpush to tests/run-tests.sh, profiles/**, .github/workflows/ci.yaml · pull_request
Clear All Notifications ▶ RunMarks all GitHub notifications as read for the authenticated user.clear-notifications.ymldispatch
Clone Org ▶ RunClones all repositories from an org or user on any supported platform (GitHub, GitLab, Bitbucket, Gitea) into Interested-Deving-1896.clone-org.ymldispatch
Fork KDE Neon Repos ▶ RunOne-shot workflow that clones the 6 KDE Invent neon repos into Interested-Deving-1896 and pushes them through the OSP mirror chain. Ongoing re-sync handled by sync-registered-imports.fork-neon-repos.ymldispatch
GitLab Storage Scan ▶ RunScans all projects under openos-project on GitLab and reports storage usage. Useful for diagnosing when the namespace approaches its 10 GiB limit.gl-storage-scan.ymlMirror OSP → GitLab completes · dispatch
HW Detect CI ▶ RunRuns CI for hardware detection tooling on schedule and push.hw-detect-ci.ymlpush to scripts/hw-detect.sh, scripts/hw-build-env.sh, scripts/kport/kport-detect*.sh (+3 more) · pull_request · dispatch
List Chromium GitLab Repos ▶ RunLists all projects under the Chromium_Browser_OS_Deving GitLab group. Informational only — used to audit what has been mirrored.list-chromium-repos.ymldispatch
Merge Repos into Monorepo ▶ RunMerges multiple git repositories into a single monorepo, preserving full commit history, tags, and Git LFS objects. Manual dispatch only.merge-to-monorepo.ymldispatch
Pre-Mirror CI Gate ▶ RunChecks CI status on all OSP-bound repos in Interested-Deving-1896 before mirroring. Dispatches resolve-failures for red repos, waits, then re-checks. Blocks the mirror if repos are still failing.pre-mirror-ci-gate.ymlReconcile Org References completes · dispatch
Repo Manifest ▶ RunExports a manifest of all repos in an org, or imports repos from a manifest into a target GitHub org. Supports multi-platform bulk import.repo-manifest.ymldispatch
Resolve CI Failures (Agnostic) ▶ RunAgnostic CI failure resolver. Runs resolve-ci.sh for each enabled target in config/ci-check-targets.yml. GitHub targets use LLM analysis and auto-fix; GitLab targets retry failed/canceled pipelines.resolve-ci.ymlCheck CI Status completes · dispatch
Setup Dashboard Variables ▶ RunSets all VITE_* repository variables required by the infra-dashboard public-dashboard build. Safe to re-run — blank inputs leave existing variables unchanged.setup-dashboard-vars.ymldispatch
Setup GitLab CI Schedules ▶ RunReplaces all existing GitLab pipeline schedules in openos-project/ops/fork-sync-all with the 3 consolidated CADENCE-based schedules. Safe to re-run.setup-gitlab-schedules.ymldispatch
Shallow Reclone Large GitLab Mirrors ▶ RunReduces GitLab storage usage by replacing full git history on large mirror projects with a shallow clone. Run when openos-project approaches its 10 GiB storage limit.shallow-reclone-chromium.ymldispatch
Trigger Artifact Mirror ▶ RunDispatches mirror-artifacts immediately when a release is published in this repo, so OSP and OOC receive the release without waiting for the next scheduled run.trigger-artifact-mirror.ymldispatch
Upload Asset ▶ RunUploads files from URLs, artifacts, or repo paths to a release, repo directory, or issue comment.upload-asset.ymldispatch

Glossary

Key terms used in this document. Full glossary: DOCS/generated/glossary.md

dispatch : Manual workflow_dispatch trigger — run from the Actions UI or via gh workflow run.

workflow_run : Trigger that fires when another named workflow completes. Used to chain workflows.

quota pre-flight : Step that checks remaining REST quota before doing API work. Sets skip=true when below MIN_QUOTA.

MIN_QUOTA : Minimum remaining REST quota required before a workflow proceeds. Per-workflow value from workflow-quota-costs.yml.

OSP : OpenOS-Project-OSP — second org in the mirror chain (GitHub).

OOC : OpenOS-Project-Ecosystem-OOC — third org in the mirror chain (GitHub).

mirror chain : Three-org pipeline: Interested-Deving-1896 → OSP → GitLab.

DRY_RUN : When true, scripts print what they would do without making changes.

SYNC_TOKEN : Cross-org GitHub token. Shares the 5000 req/hr bucket with GH_TOKEN.

OTA : Over-the-air update system delivering workflow/config updates to consumer repos.

pre-flush-prep : Pre-flight workflow run before full-chain-flush.

full-chain-flush : End-to-end pipeline: pre-flush-prep → mirror chain → post-flush-prep.

priority tiers : Tier 1 CRITICAL → Tier 4 LOW. Controls queue-manager and quota-reserve cancellation order.

consumer repo : Repo receiving template files from fork-sync-all via sync-template.sh.

OSP-bound repo : Repo mirrored into OSP and managed by fork-sync-all.

Schedule Summary (UTC)

TimeFrequencyWorkflow
00:00DailySync Upstream Mirrors (GitLab) ▶ Run
Sun 01:00WeeklyManage Subtrees ▶ Run
01:00DailySync KDE Groups Mirrors ▶ Run
01:07DailySync pieroproietti Forks ▶ Run
at :10Every 1hRunner Status ▶ Run
01:23DailyMirror OSP → GitLab ▶ Run
01:30DailySync KDE Neon Mirrors ▶ Run
01:37DailySync Upstream Sources ▶ Run
01:50DailySync to GitLab Variant ▶ Run
Sun 02:00WeeklyOrg Storage Maintenance ▶ Run
Sun 02:00WeeklySync Shell Tools Vendor ▶ Run
02:10DailyMirror Artifacts ▶ Run
02:15DailySync Pieroproietti GitLab Forks ▶ Run
02:17DailyMirror Orgs ▶ Run
Tue 02:41WeeklyGenerate SBOM ▶ Run
02:45DailySetup OSP Mirror Workflows ▶ Run
Sun 03:00WeeklyIntegrate Shell Tools ▶ Run
03:00DailyMirror GHCR Images ▶ Run
Mon 03:00Weeklybtrfs-devel sync ▶ Run
03:05DailySync Registry Sources ▶ Run
Sun 03:08WeeklyDocker → Incus Migration ▶ Run
Sun 03:10WeeklyGenerate OSP Dependency Graph ▶ Run
03:15DailyUpdate READMEs ▶ Run
Wed 03:17WeeklyOTA Reconcile ▶ Run
1st 03:19MonthlyLTS README Standardisation ▶ Run
Sun 03:30WeeklyGenerate Repo Descriptions ▶ Run
03:33DailyUpstream PRs from OSP + OOC ▶ Run
03:47DailyUpstream Direct Commits from OSP + OOC ▶ Run
Mon 04:00WeeklyAudit Arch Repos ▶ Run
Mon 04:00WeeklyFull Audit ▶ Run
04:00DailySync FSA Forks ▶ Run
at :05Every 4hRate-Limit Re-trigger ▶ Run
Mon 04:17WeeklyCheck Accessibility ▶ Run
Mon 04:17WeeklyGitBook OSS ▶ Run
Mon 04:23WeeklyVouch Sync Codeowners ▶ Run
04:27DailyGit Platform Sync ▶ Run
1st 04:29MonthlyCleanup Stale Branches ▶ Run
Mon 04:30WeeklyManage Repo Settings ▶ Run
04:30DailyMirror RPM Repo ▶ Run
at :32Every 4hNotification Poller ▶ Run
04:55DailySync Registered Imports ▶ Run
Sun 05:00WeeklyEco Audit ▶ Run
05:00DailyMirror Flatpak Repo ▶ Run
Tue 05:00WeeklyPin Workflow Actions ▶ Run
Tue 05:00WeeklySync UAA Vendor ▶ Run
05:02DailySync btrfs-devel Branches ▶ Run
10 5 */2 * *Rebase PRs ▶ Run
Mon 05:15WeeklyOTA Self-Update ▶ Run
1st 05:17MonthlyFull Chain Flush ▶ Run
50 5 */2 * *Reconcile Org References ▶ Run
Sun 06:00WeeklyFlush Lifecycle Manager ▶ Run
Mon 06:00WeeklyHW Detect CI ▶ Run
Mon 06:00WeeklyPin Manager ▶ Run
06:00DailySync Ona Projects ▶ Run
Mon 06:06WeeklyUpstream Workflow Proposal ▶ Run
06:07DailySync All Forks ▶ Run
Mon 06:11WeeklyUpdate Infrastructure Dependencies ▶ Run
at :13Every 6hMirror Interested-Deving-1896 → OSP ▶ Run
Tue 06:17WeeklyRefresh NotebookLM Auth ▶ Run
Mon 06:25WeeklyVerify Fork Integrity ▶ Run
06:30DailyCheck OOC CI Status ▶ Run
Mon 06:30WeeklyCheck Shell Tools CI ▶ Run
at :37Every 6hSync-in ▶ Run
06:38DailyOTA Discover ▶ Run
at :45Every 6hMirror to OpenOS-Project-Ecosystem-OOC ▶ Run
at :55Every 6hAuto-merge PRs ▶ Run
07:00DailyPin Manager ▶ Run
07:08DailyCreate Missing READMEs ▶ Run
07:43DailyResolve CI Failures ▶ Run
07:43DailyResolve CI Failures (Agnostic) ▶ Run
Mon 08:00WeeklyUpdate Quota Cost Registry ▶ Run
15 8 */2 * *Inject Built-with-Ona Badges ▶ Run
30 8 */2 * *Inject Repo Motto ▶ Run
Mon 09:00WeeklySync Agent Prices ▶ Run
09:05DailyCheck CI Status ▶ Run
09:23DailyGit Platform Sync ▶ Run
Mon 09:24WeeklyToken Health Monitor ▶ Run
10:15DailySync-in ▶ Run
Mon 10:34WeeklyCodeQL ▶ Run
43 10 */2 * *Translate READMEs ▶ Run
15 11 */2 * *Translate Docs ▶ Run
at :03Every 12hMirror Releases ▶ Run
Mon 14:00WeeklyBranch Hygiene Report ▶ Run
0 * * * *Mirror to OpenOS-Project-OSP ▶ Run
15 * * * *Mirror to OpenOS-Project-Ecosystem-OOC ▶ Run
17 * * * *Notification Manager ▶ Run
Every 30 minList Active Runs ▶ Run
Every 30 minQueue Manager ▶ Run
Every 30 minQuota Reserve ▶ Run

Workflow Scheduling Guide

Optimal trigger windows, quota requirements, and timing constraints for every scheduled workflow. Use this when deciding when to manually dispatch a workflow or when to adjust a cron schedule.


How to read this guide

Quota cost — REST API calls consumed per run (mid = typical, high = worst case). Source: config/workflow-quota-costs.yml. GraphQL calls count as 1 REST call regardless of how many repos are queried.

Best window — the UTC hour range where quota headroom is highest and concurrency with other workflows is lowest.

Avoid — hours where the scheduled burst is already high or where a dependency workflow hasn't finished yet.

Quota floor — the minimum remaining quota required before the workflow will run (from min_quota in config/workflow-quota-costs.yml). If quota is below this, the workflow skips itself and waits for the next reset.


Time format note

Per-workflow tables show two schedule columns:

  • Schedule (UTC) — 24h UTC, the authoritative cron time
  • Schedule (EST) — EST (UTC−5, Nov–Mar). Add 1h for EDT (UTC−4, Mar–Nov).

Example: 09:05 UTC = 4:05 AM EST = 5:05 AM EDT.

The timing map and "Best manual dispatch windows" tables use the full 24h UTC / 12h UTC / 12h ET (EST/EDT) format for completeness.


Daily quota budget

MetricValue
Quota per hour5,000 REST calls
Scheduled drain (daily avg)~3,200 calls/day (~133/hr average)
Worst scheduled burst (03:xx UTC / 3:xx AM UTC / 10:xx PM ET)~612 calls in one hour
Headroom at worst hour~4,388 calls remaining
Safe manual dispatch windowAny hour with < 2,000 calls already consumed

Check current quota before dispatching:

curl -sf -H "Authorization: token $SYNC_TOKEN" \
  "https://api.github.com/rate_limit" | \
  python3 -c "
import sys,json,datetime
d=json.load(sys.stdin)['resources']['core']
print(f\"remaining={d['remaining']}  resets={datetime.datetime.utcfromtimestamp(d['reset']).strftime('%H:%M UTC')}\")
"

Scheduled workflow timing map

All times UTC (24h) with 12h UTC and approximate ET equivalents. [*/2] = every other day (even days of month). (*/30) = every 30 min.

Hour (UTC)     12h UTC        ET (EDT/EST)    Workflows
─────────────────────────────────────────────────────────────────────────────
00:xx          12:xx AM       8:xx PM / 7:xx PM    mirror-to-osp (:13)  sync-in (:37)
                                                    mirror-osp-to-ooc (:45)  auto-merge-prs (:55)
01:xx          1:xx AM        9:xx PM / 8:xx PM    sync-pieroproietti-forks (:07)
                                                    mirror-osp-to-gitlab (:23)
                                                    sync-to-gitlab-variant (:50)
02:xx          2:xx AM        10:xx PM / 9:xx PM   mirror-artifacts (:10)  mirror-orgs-full (:17)
                                                    setup-osp-mirrors (:45)
03:xx          3:xx AM        11:xx PM / 10:xx PM  upstream-prs (:33)  upstream-commits (:47)
04:xx          4:xx AM        12:xx AM / 11:xx PM  git-platform-sync/pull (:27)
                                                    sync-registered-imports (:55)
05:xx          5:xx AM        1:xx AM / 12:xx AM   sync-btrfs-devel-branches (:02)
                                                    rebase-prs [*/2] (:10)
                                                    reconcile-org-refs [*/2] (:50)
06:xx          6:xx AM        2:xx AM / 1:xx AM    queue-manager (*/30)  quota-reserve (*/30)
                                                    [Mon only: update-infra-deps (:11)]
07:xx          7:xx AM        3:xx AM / 2:xx AM    resolve-ci (:43)
08:xx          8:xx AM        4:xx AM / 3:xx AM    check-ci (:05)  inject-badges [*/2] (:15)
09:xx          9:xx AM        5:xx AM / 4:xx AM    git-platform-sync/push (:23)
                                                    check-shell-tools-ci (:30)
10:xx          10:xx AM       6:xx AM / 5:xx AM    sync-in/daily (:15)
                                                    translate-readmes [*/2] (:43)
11:xx          11:xx AM       7:xx AM / 6:xx AM    translate-docs [*/2] (:15)
12:xx–23:xx    12:xx PM–      8:xx AM–             mirror-releases (:03 at 12:xx)
               11:xx PM       7:xx PM              queue-manager + quota-reserve (*/30, all hours)

Per-workflow scheduling reference

Core mirror chain

WorkflowSchedule (UTC)Schedule (EST)Quota midQuota highFloorBest window (UTC)Avoid
Mirror I-D-1896 → OSPEvery 6h at :13Every 6h at :1380200300After 14:00 reset00:00–06:00 (busy)
Mirror OSP → OOCEvery 6h at :45Every 6h at :458020030032 min after mirror-to-ospBefore :13 slot
Mirror OrgsDaily 02:17Daily 9:17 PM6015020002:00–04:0006:xx (weekly burst)
Mirror OSP → GitLabDaily 01:23Daily 8:23 PM8020020001:00–03:00During mirror chain
Mirror ReleasesEvery 12h at :03 (00:03 + 12:03)7:03 PM + 7:03 AM10030020000:03 or 12:03During flush
Mirror ArtifactsDaily 02:10Daily 9:10 PM8020020002:00–04:00During flush

Mirror chain dependency order: Mirror I-D-1896 → OSP must complete before Mirror OSP → OOC. The :13/:45 stagger (32 min gap) is intentional — do not reduce this gap when manually dispatching both.


CI check + resolver

WorkflowSchedule (UTC)Schedule (EST)Quota midQuota highFloorBest window (UTC)Avoid
Check CI StatusDaily 09:054:05 AM300900150009:00–11:00During flush
Resolve CI Failures (Agnostic)Daily 07:432:43 AM12040010007:00–09:00During flush
Check Shell Tools CIDaily 09:304:30 AM5010020009:00–11:00

Note: Check CI Status requires a 1,500 quota floor — the highest of any workflow. If quota is below 1,500 at 09:05 UTC (4:05 AM EST / 5:05 AM EDT), it skips and waits for the next day. Manually dispatch after the 14:00 UTC reset if you need it to run same-day.


Sync operations

WorkflowSchedule (UTC)Schedule (EST)Quota midQuota highFloorBest window (UTC)Avoid
Sync All ForksVia full-chain-flush20050050004:00–08:00During mirror chain
Sync Registered ImportsDaily 04:5511:55 PM4510020004:00–06:00
Sync btrfs-devel BranchesDaily 05:0212:02 AM308010005:00–07:00
Sync pieroproietti ForksDaily 01:078:07 PM6015020001:00–03:00
Sync to GitLab VariantDaily 01:508:50 PM4010010001:00–03:00
Setup OSP Mirror WorkflowsDaily 02:459:45 PM8020020002:00–04:00
Git Platform SyncDaily 04:27 + 09:2311:27 PM + 4:23 AM6015020004:00 or 09:00
Upstream PRs from OSP+OOCDaily 03:3310:33 PM8020030003:00–05:00
Upstream Direct CommitsDaily 03:4710:47 PM80200300After upstream-prs (:33)Before :33 slot

README + badge operations

WorkflowSchedule (UTC)Schedule (EST)Quota midQuota highFloorBest window (UTC)Avoid
Update READMEsVia flush15040050010:00–12:00During mirror chain
Create Missing READMEsVia flush10030030010:00–12:00
Inject Built-with-Ona BadgesEvery 2 days 08:153:15 AM12030030008:00–10:00
Translate READMEsEvery 2 days 10:435:43 AM15040030010:00–12:00
Translate DocsEvery 2 days 11:156:15 AM10025020011:00–13:00
Reconcile Org ReferencesEvery 2 days 05:5012:50 AM8020020005:00–07:00

Infrastructure / quota management

WorkflowSchedule (UTC)Schedule (EST)Quota midQuota highFloorNotes
Queue ManagerEvery 30 minEvery 30 min153050Never manually dispatch — runs automatically
Quota ReserveEvery 30 minEvery 30 min153050Never manually dispatch
Rate-Limit Re-triggerEvery 6hEvery 6h3080100Fires automatically after quota recovery
Auto-merge PRsEvery 6h at :55 (00:55, 06:55, 12:55, 18:55)7:55 PM, 1:55 AM, 7:55 AM, 1:55 PM3080100Safe to dispatch any time
Rebase PRsEvery 2 days 05:1012:10 AM40100100Safe to dispatch any time

Heavy / manual-only workflows

WorkflowTriggerSchedule (EST)Quota midQuota highFloorBest window (UTC)
Full Chain FlushManual / daily 05:1712:17 AM4001000100004:00–08:00
Pre-Flush PrepManual only50150300014:05 (5 min after reset)
Critical DeployManual only100300500Any time — bypasses queue
Onboard RepoManual only80200300Any time
Add Mirror RepoManual only60150200Any time
Sync Ona ProjectsDaily 06:00 / manual1:00 AM12050Any time — dry-run by default on schedule

Pre-Flush Prep has the highest floor (3,000) because it validates config, merges PRs, and then dispatches the full flush chain. Trigger it immediately after the 14:00 UTC (9:00 AM EST / 10:00 AM EDT) reset for maximum headroom.


Best manual dispatch windows

Highest quota headroom

Window24h UTC12h UTCET (EDT)ET (EST)Why
Best14:00–15:002:00–3:00 PM10:00–11:00 AM9:00–10:00 AMImmediately after hourly reset; ~4,867 calls available
Good05:00–07:005:00–7:00 AM1:00–3:00 AM12:00–2:00 AMLow scheduled activity; ~4,400 calls typically available
Good20:00–23:008:00–11:00 PM4:00–7:00 PM3:00–6:00 PMNo scheduled workflows; quota recovering

Lowest concurrency (fewest parallel jobs)

Window24h UTC12h UTCET (EDT)ET (EST)Why
Best15:00–17:003:00–5:00 PM11:00 AM–1:00 PM10:00 AM–12:00 PMNo scheduled workflows at all
Good11:00–13:0011:00 AM–1:00 PM7:00–9:00 AM6:00–8:00 AMOnly translate workflows (every 2 days); runners mostly idle

Avoid

Window24h UTC12h UTCET (EDT)ET (EST)Why
Worst03:00–04:003:00–4:00 AM11:00 PM–12:00 AM10:00–11:00 PMHighest burst (~612 calls); upstream PRs + commits + sync all fire
Caution06:00–07:006:00–7:00 AM2:00–3:00 AM1:00–2:00 AMMonday only: 13-workflow concurrent spike (update-infra-deps)
Caution09:00–10:009:00–10:00 AM5:00–6:00 AM4:00–5:00 AMCheck CI Status fires (1,500 floor); marginal quota risks skipping it

Pre-flush-prep checklist

Before triggering pre-flush-prep.yml:

# 1. Check quota
curl -sf -H "Authorization: token $SYNC_TOKEN" \
  "https://api.github.com/rate_limit" | \
  python3 -c "
import sys,json,datetime
d=json.load(sys.stdin)['resources']['core']
reset=datetime.datetime.utcfromtimestamp(d['reset']).strftime('%H:%M UTC')
ok = '✅' if d['remaining'] >= 3000 else '❌'
print(f\"{ok} remaining={d['remaining']} (need 3000)  resets={reset}\")
"

# 2. Run validators locally
python3 scripts/validate-workflow-guards.py
python3 scripts/validate-gitlab-subgroups.py config/gitlab-subgroups.yml
python3 scripts/validate-registered-imports.py registered-imports.json
python3 scripts/validate-priority-tiers.py config/workflow-priority-tiers.yml
python3 scripts/validate-cost-profiles.py config/workflow-cost-profiles.yml

# 3. Check for open PRs that would block the flush
gh pr list --state open --json number,title,mergeable

Ideal trigger time:

24h UTC12h UTCET (EDT)ET (EST)
14:052:05 PM10:05 AM9:05 AM

5 minutes after the hourly reset — maximum quota headroom before any scheduled workflows consume from the fresh bucket.


Quota drain reduction history

DateChangeSaving
2026-06Removed schedule from check-osp-ci + check-ooc-ci stubs−600/day
2026-06auto-merge-prs: 2h → 6h−240/day
2026-06upstream-prs + upstream-commits: 6h → daily−480/day
2026-06setup-osp-mirrors: 6h → daily−240/day
2026-06sync-to-gitlab + sync-from-gitlab stubs: removed schedule−0 cost, freed runner slots
2026-06sync-btrfs-devel + sync-registered-imports: 6h → daily−105/day
2026-06mirror-releases: 6h → 12h−100/day
2026-06sync-to-gitlab-variant + sync-pieroproietti + mirror-osp-to-gitlab + mirror-artifacts: 8h → daily−480/day
2026-06reconcile-org-refs + rebase-prs + inject-badges + translate-readmes + translate-docs: daily → every 2 days−300/day
Total−2,545/day (−46% from 5,495 baseline)

Current baseline: ~3,200 calls/day (~133/hr average).


Remaining quota reduction opportunities

These are known but not yet applied — each has a trade-off noted.

OpportunityPotential savingTrade-off
Convert sync-forks.sh REST repo loop → GraphQL prefetch~200/runCode change required in script
Convert reconcile-org-refs.sh REST loop → GraphQL~100/runCode change required
mirror-releases.yml: 12h → daily~50/dayReleases delayed up to 24h
resolve-ci.yml: remove daily schedule, trigger-only~60/dayFailures only resolved when check-ci fires
check-shell-tools-ci.yml: daily → every 2 days~25/dayShell tools CI lag
Add actions/cache@v5 to full-audit.yml (pyyaml)runner time onlyTrivial
Add actions/cache@v5 to check-accessibility.yml (pa11y)runner time onlyTrivial
sync-pieroproietti-gl-forks.sh: migrate to gh_getreliabilityRaw curl has no retry

Speed improvement opportunities

Scripts

ScriptIssueFix
sync-forks.shSequential REST calls per repoGraphQL prefetch for repo list + existence
reconcile-org-refs.shPaginated REST for org reposGraphQL batch query
update-readmes.shPer-repo /contents/README.md callsTree fetch with ?recursive=1 then filter
resolve-failures.shSequential per-repo run scanParallel with xargs -P 4 for log fetches
sync-pieroproietti-gl-forks.shRaw curl without retrySource includes/gh-api.sh, use gh_get

Workflows

WorkflowIssueFix
full-audit.ymlpip install pyyaml on every runAdd actions/cache@v5
check-accessibility.ymlnpm install -g pa11y on every runAdd actions/cache@v5
validate-config.yml✅ Already cached (pytest, yamllint, gavi)
critical-deploy*.ymlfetch-depth: 0 (full history)Only needed for git log — use fetch-depth: 1 + git fetch --unshallow only when needed
sync-shell-tools.ymlfetch-depth: 0Same as above
manage-subtrees.ymlfetch-depth: 0Required for subtree — keep
sync-uaa-vendor.ymlfetch-depth: 0Required for vendor merge — keep

Runner minutes

Public repos on GitHub get unlimited free runner minutes. If this repo is public, runner minutes are not a constraint. If private:

  • Current worst-case estimate: ~8,000 min/month (well over 2,000 free tier)
  • Self-hosted runner eliminates the cap entirely
  • Alternatively: reduce timeout-minutes on workflows that consistently finish in < 5 min but have 30 min timeouts — this doesn't save minutes (billing is actual runtime, not timeout) but prevents runaway jobs

Workflows with oversized timeouts relative to typical runtime:

Workflowtimeout-minutesTypical runtimeSuggested
Queue Manager10< 1 min5
Quota Reserve10< 1 min5
Auto-merge PRs151–3 min8
Rebase PRs202–5 min10
Reconcile Org Refs305–10 min15

Quota Cost Registry

GitHub's REST API allows 5,000 requests per hour per user (shared across all tokens belonging to the same user). This page documents how many REST calls each workflow consumes per run, the minimum quota required before a workflow should start, and how the quota management system uses this data.

GraphQL counts as 1 call regardless of how many repos are queried. raw.githubusercontent.com fetches are exempt entirely.


How quota is managed

Three mechanisms work together:

MechanismWhereWhat it does
quota-reserve.shRuns every 30 minCancels queued low-priority runs when remaining < RESERVE_FLOOR (default: 1000). Uses min_quota per workflow to also cancel runs that couldn't succeed with current quota even if they started.
budget_check()Inside each script loopStops processing mid-run when time budget is exhausted. Prevents a single run from consuming all quota in one shot.
workflow_min_quota()Pre-flight stepsReturns the min_quota for a workflow from config/workflow-quota-costs.yml. Workflows can use this to skip themselves when quota is too low.

The single source of truth for costs is config/workflow-quota-costs.yml.


Cost table

Costs are estimated from code audit (Phase 1). Phase 2 will replace these with observed p50/p95 values from actual run measurements.

min_quota = minimum REST calls required before this workflow should be allowed to start.

Tier 1 — Critical (never cancelled)

Workflowmin_quotaLowMidHighNotes
Rotate Secret Token5051020Token validation + secret update
Queue Manager5051530Queued run list + cancel calls
Quota Reserve101515rate_limit check (exempt) + cancels
Rate-Limit Re-trigger5052050Failed run scan + dispatch calls
Token Health Monitor5051020Token validation only
CI502510ShellCheck + lint, minimal API
Pre-Flush Prep100103060PR list + check-run queries

Tier 2 — High

Workflowmin_quotaLowMidHighNotes
Mirror Interested-Deving-1896 → OSP50020802002 GraphQL + 1 REST/repo (check-runs, gated)
Mirror OSP → GitLab300520501 GraphQL for repo list; GitLab calls exempt
Sync Registered Imports200515301 GraphQL prefetch; REST only for new repos
Sync All Forks500502005001 GraphQL + 1 REST merge-upstream per fork
Full Chain Flush10001004001000Orchestrates chain — cost is additive
Add Mirror Repo200103060Repo creation + webhook + dispatch

Tier 3 — Medium

Workflowmin_quotaLowMidHighNotes
Update READMEs30050150300Tree fetch + file reads/writes per repo
Create Missing READMEs2002080200Same as Update READMEs, subset of repos
Inject Built-with-Ona Badges200530801 GraphQL (repo list + README); REST only on write
Reconcile Org References30010601501 GraphQL repo list; pushedAt from cache
Check OSP-Bound CI Status300501503004 REST/repo (check-runs not in GraphQL)
Rebase PRs10052050PR list + rebase trigger
Sync btrfs-devel Branches10052050Branch sync per tracked branch
Sync pieroproietti Forks1001040100merge-upstream per fork branch
Setup OSP Mirror Workflows20020802001 GraphQL + workflow/secrets per repo (not in GraphQL)
Upstream PRs from OSP + OOC2002080200PR creation/update per diverged repo
Upstream Direct Commits from OSP + OOC2002080200Commit compare + PR creation
Sync to GitLab10052050GitHub reads; GitLab writes exempt
Sync to GitLab Variant10052050Same as Sync to GitLab
Sync from GitLab10052050GitLab reads + GitHub writes
Notification Poller501515Single notifications call + optional dispatch

Tier 4 — Low (cancelled first)

Workflowmin_quotaLowMidHighNotes
Translate READMEs1001040100File read + write per README
LTS README Standardisation1001040100File read + write per LTS repo
Generate OSP Dependency Graph1002060150README + package.json reads per repo
Upstream Workflow Proposal5052050Workflow file reads + PR creation
Update Infrastructure Dependencies5051530Dependabot config + PR creation
Mirror Artifacts20010501502 GraphQL; release asset downloads exempt
Mirror Releases20010501502 GraphQL + 1 REST releases list per repo
Cleanup Stale Branches20010602001 GraphQL + 1 REST compare per branch
OTA Discover1001040100Fork list + config reads per fork
OTA Self-Update5051530Config read + PR creation
Mirror Orgs1002060150Repo list + description reads per org
Resolve CI Failures1001040100Failed run list + job details + file writes

Daily quota budget

At 5,000 calls/hour reset, the effective daily budget depends on how many resets are consumed cleanly vs. drained by backlog. With the schedule reductions applied (June 2026), the expected daily workflow run count dropped by ~172 runs/day.

CategoryBeforeAfter
quota-reserve runs/day14448
queue-manager runs/day9648
notify-poller runs/day126
rate-limit-rerun runs/day126
mirror-artifacts runs/day63
mirror-osp-to-gitlab runs/day63
sync-pieroproietti-forks runs/day63
sync-to-gitlab-variant runs/day63

REST → GraphQL conversion log

Scripts converted from per-repo REST loops to batched GraphQL calls:

ScriptSavings/runRuns/daySaved/day
sync-registered-imports.sh~1004~400
mirror-osp-to-gitlab.sh~23~6
reconcile-org-refs.sh~1006~600
inject-badges.sh~503~150
cleanup-branches.sh~2001~200
mirror-releases.sh~504~200
mirror-artifacts.sh~503~150
ota-discover.sh~501~50
mirror-orgs.sh~601~60
setup-osp-mirrors.sh~1004~400
Total~2,216/day

Phase 2: observed cost tracking (planned)

Phase 2 will add lightweight instrumentation to measure actual REST consumption per run:

  1. scripts/includes/quota-instrument.sh — records remaining_before and remaining_after as workflow step summary annotations
  2. update-quota-costs.yml — weekly workflow that reads the last 30 run summaries via GraphQL, computes p50/p95 per workflow, and commits updated values back to config/workflow-quota-costs.yml with basis: observed

Once Phase 2 is active, the tables above will show observed values alongside the code-audit estimates, and quota-reserve.sh will automatically use the more accurate figures.

Operational Reference: GitHub Actions Limits & Quotas

This document covers the GitHub Actions limits that affect fork-sync-all, what consumes them, how to detect exhaustion, and how to recover.


GitHub API Rate Limit

Quota: 5,000 requests/hour per authenticated user token.

Resets: Top of every hour (rolling window).

What consumes it:

OperationCost
gh api / REST API call1 req
Listing workflow runs1 req per page
Cancelling a run1 req
Triggering a workflow dispatch1 req
Checking job status1 req per job
GraphQL querySeparate quota (5,000 points/hr) — unaffected by REST exhaustion

How fork-sync-all burns it:

  • Every workflow_run trigger fires a new run, which itself may call the API
  • rate-limit-rerun.yml (formerly hourly) scans all recent failed runs
  • stuck-run-detector.yml (formerly hourly) lists all queued/in-progress runs
  • translate-readmes.yml was triggering after 10 workflows — each trigger consumed dozens of API calls for the org scan
  • Bulk-cancelling queued runs during cleanup consumes ~1 req per cancel — if the queue is large and quota is already low, the cancel loop itself can exhaust the remaining quota

Detecting exhaustion:

gh api rate_limit --jq '.resources.core | "remaining: \(.remaining)/\(.limit)  resets: \(.reset | todate)"'

Recovery: Wait until the top of the next hour. GraphQL remains available during REST exhaustion and can be used for read-only queries.


GitHub Actions Runner Minutes

Free tier: 2,000 minutes/month. Resets on your billing cycle date (the day of the month your GitHub account was created — check Settings → Billing → Actions for the exact date).

Paid: Billed per minute beyond the free tier; Linux runners cost 1×, Windows 2×, macOS 10×. All workflows in this repo use ubuntu-latest (Linux, 1×).

What counts against the monthly quota:

  • Every job that runs on ubuntu-latest (GitHub-hosted runner)
  • Time is measured from job start to job end, rounded up to the nearest minute
  • Jobs that are queued but never start do not consume minutes
  • Jobs that exit immediately (e.g. if: condition is false at the job level) still consume ~1 minute for runner provisioning

What does NOT count:

  • workflow_dispatch triggers that are never clicked
  • Runs that are cancelled before a job starts
  • Skipped jobs (if: evaluated to false before the runner is assigned)
  • Self-hosted runners (zero cost regardless of usage)

How fork-sync-all was burning minutes (before May 2026 fixes):

  1. mirror-orgs-watchdog fired after every mirror completion (5 workflows × hourly cadence = ~120 runs/day), each consuming ~1 min even on success
  2. update-readmes triggered after 7 workflows including high-frequency syncs
  3. inject-badges triggered after mirror workflows that run hourly
  4. stuck-run-detector and rate-limit-rerun ran hourly as meta-workflows, each consuming minutes to manage other workflows
  5. workflow_run listeners fired on every completed event (success, failure, cancelled) — not just on the outcomes they actually needed

Detecting exhaustion:

Symptoms (in order of appearance):

  1. ubuntu-latest jobs queue but never start
  2. No in-progress runs despite many queued
  3. Runs queued for hours with 0 runners active
  4. Billing API returns 404 (needs user OAuth scope — check web UI instead)

Check via GitHub web UI: Settings → Billing → Actions.

Recovery: Wait until the billing cycle reset date. In the meantime:

  • Cancel all queued runs (they will never start)
  • Do not push commits that trigger new workflow runs
  • Use workflow_dispatch manually only for critical operations

Concurrency Groups & Stuck Runs

How they work: A concurrency group allows only one run at a time for a given key. If cancel-in-progress: false, a second run queues behind the first. If the first run never finishes (e.g. runner minutes exhausted mid-job), the queued run is permanently stuck.

The cascade pattern:

  1. Runner minutes exhaust mid-job → job hangs in in_progress
  2. Next scheduled run queues behind it (cancel-in-progress: false)
  3. The in-progress run never finishes → queue grows indefinitely
  4. API calls to cancel are themselves rate-limited → nothing can be cleared

Orphaned runs: A run can become permanently orphaned if it was triggered from an older version of a workflow file that contained a job (e.g. Update cost profile) that no longer exists in the current file. The run accepts cancel API calls but GitHub immediately re-queues it because the concurrency group from the old code is still technically active. These runs time out automatically after GitHub's maximum queue wait (~6 hours). New runs from the same workflow are not blocked — they use the current file.

Policy in this repo (May 2026): All workflows use cancel-in-progress: true except those that perform multi-repo writes where mid-run cancellation would leave state partially applied:

Workflowcancel-in-progressReason
sync-templatefalsePropagates files to 35 repos — partial sync leaves repos inconsistent
mirror-releasesfalsePartial mirror leaves releases incomplete
lts-readmesfalseMid-run cancel leaves some repos un-standardised
mirror-osp-to-gitlabfalsePartial GitLab mirror
create-readmesfalseMid-run cancel leaves some repos without READMEs
mirror-artifactsfalsePartial artifact mirror
All otherstrueNewer run supersedes safely

Detecting stuck runs:

gh api "repos/Interested-Deving-1896/fork-sync-all/actions/runs?per_page=100" \
  --jq '[.workflow_runs[] | select(.status == "queued")] | length'

Bulk cancel (check quota first — cancel loop consumes ~1 req per run):

gh api rate_limit --jq '.resources.core.remaining'

gh api "repos/Interested-Deving-1896/fork-sync-all/actions/runs?per_page=100" \
  --jq '[.workflow_runs[] | select(.status=="queued") | .id] | .[]' | \
  xargs -I{} gh api -X POST \
    "repos/Interested-Deving-1896/fork-sync-all/actions/runs/{}/cancel"

workflow_run Trigger Cost Model

workflow_run fires on every completed event regardless of conclusion (success, failure, cancelled, skipped). A listener that only needs to act on failures still consumes a runner minute for every successful upstream run unless gated at the job level.

Pattern used in this repo:

# For workflows that act on upstream SUCCESS (content processors):
jobs:
  my-job:
    if: |
      github.event_name != 'workflow_run' ||
      github.event.workflow_run.conclusion == 'success'

# For workflows that act on upstream FAILURE (watchdogs/retriers):
jobs:
  retry:
    if: |
      github.event_name == 'workflow_dispatch' ||
      github.event.workflow_run.conclusion == 'failure'

This exits immediately (no runner cost) when the conclusion doesn't match, while keeping the trigger automatic.

All workflow_run listeners and their gates (May 2026):

WorkflowGate
mirror-orgs-watchdogconclusion == 'failure'
create-readmesconclusion == 'success'
inject-badgesconclusion == 'success'
lts-readmesconclusion == 'success'
mirror-osp-to-gitlabconclusion == 'success'
translate-readmesconclusion == 'success' (on gate job)
update-readmesconclusion == 'success'
dwarfs-pack-callerconclusion == 'success'
rebase-ltsconclusion == 'success'

Current Workflow Schedule Summary

Schedules as of June 2026. All times UTC (24h) / UTC (12h) / ET (EDT, UTC−4). See DOCS/workflow-scheduling.md for full per-workflow quota and window details.

Workflow24h UTC12h UTCET (EDT)CadenceNotes
mirror-to-osp:13:13 AM/PM−4hEvery 6hCore mirror chain start
mirror-osp-to-ooc:45:45 AM/PM−4hEvery 6h32 min after mirror-to-osp
sync-in:37:37 AM/PM−4hEvery 6h + daily 10:15Health check + workspace sync
auto-merge-prs:55:55 AM/PM−4hEvery 6h
queue-manager:00/:30:00/:30 AM/PM−4hEvery 30 minInfrastructure
quota-reserve:00/:30:00/:30 AM/PM−4hEvery 30 minInfrastructure
mirror-releases00:03 + 12:0312:03 AM + 12:03 PM8:03 PM + 8:03 AMEvery 12h
sync-pieroproietti-forks01:071:07 AM9:07 PMDailyReduced from 8h
mirror-osp-to-gitlab01:231:23 AM9:23 PMDailyReduced from 8h
sync-to-gitlab-variant01:501:50 AM9:50 PMDailyReduced from 8h
mirror-artifacts02:102:10 AM10:10 PMDailyReduced from 8h
mirror-orgs-full02:172:17 AM10:17 PMDaily
setup-osp-mirrors02:452:45 AM10:45 PMDailyReduced from 6h
upstream-prs03:333:33 AM11:33 PMDailyReduced from 6h
upstream-commits03:473:47 AM11:47 PMDailyReduced from 6h
git-platform-sync04:27 + 09:234:27 AM + 9:23 AM12:27 AM + 5:23 AMDaily ×2Pull + push
sync-registered-imports04:554:55 AM12:55 AMDailyReduced from 6h
sync-btrfs-devel-branches05:025:02 AM1:02 AMDailyReduced from 6h
rebase-prs05:105:10 AM1:10 AMEvery 2 daysReduced from daily
flush-lifecycleSun 06:006:00 AM Sun2:00 AM SunWeekly + manualTop-level pipeline entry point
full-chain-flush05:175:17 AM1:17 AMMonthly (1st) + via flush-lifecycleTriggered by flush-lifecycle or pre-flush-prep
reconcile-org-refs05:505:50 AM1:50 AMEvery 2 daysReduced from daily
resolve-ci07:437:43 AM3:43 AMDaily
check-ci09:059:05 AM5:05 AMDaily1,500 quota floor
check-shell-tools-ci09:309:30 AM5:30 AMDaily
inject-badges08:158:15 AM4:15 AMEvery 2 daysReduced from daily
translate-readmes10:4310:43 AM6:43 AMEvery 2 daysReduced from daily
translate-docs11:1511:15 AM7:15 AMEvery 2 daysReduced from daily
refresh-notebooklm-auth06:17 Tue6:17 AM Tue2:17 AM TueWeekly
update-infra-deps06:11 Mon6:11 AM Mon2:11 AM MonWeekly

Estimated daily drain: ~3,200 REST calls/day (~133/hr average). Worst hourly burst: ~612 calls at 03:xx UTC / 3 AM UTC / 11 PM ET. Headroom at worst hour: ~4,388 calls (well within 5,000/hr limit).

For optimal manual dispatch windows, see DOCS/workflow-scheduling.md.


To eliminate the monthly minute cap entirely, add a self-hosted runner:

  1. Go to Settings → Actions → Runners → New self-hosted runner
  2. Follow the setup instructions for your host OS
  3. Change workflow runs-on from ubuntu-latest to self-hosted (or add a label and use that label)

Self-hosted runners have no minute cost and no concurrent job cap beyond what the host machine can handle.


Quick Reference: Limit Reset Times

LimitResets
GitHub API rate limit (REST)Top of every hour
GitHub API rate limit (GraphQL)Top of every hour (separate quota)
GitHub Actions minutesBilling cycle date (check Settings → Billing)
GitHub Actions concurrent jobs (free)N/A — blocked by minute exhaustion

AI Agent Cost Reference

Budgeting guide for AI agent usage on fork-sync-all. Covers all agents used in this repo: Ona Agent (Claude), Codex, GitHub Models (GPT-4o/mini), and direct Anthropic API. Includes token economics, per-task cost estimates, and package selection guidance.


Ona Compute Units (OCUs)

An OCU is Ona's billing unit. It covers both environment runtime and AI model inference. OCUs are not raw tokens — Ona bundles compute + model calls into a single unit.

Top-up packages (one-time, valid 1 year with active subscription)

PackageOCUsUSDUSD/OCU
Starter40$10$0.25
Small100$25$0.25
Medium200$50$0.25
Large400$100$0.25
XL1,000$250$0.25
2XL2,000$500$0.25
3XL4,000$1,000$0.25
4XL8,000$2,000$0.25

All tiers are a flat $0.25/OCU — no bulk discount on top-ups.

Core subscription (monthly, resets each period, does not roll over)

Monthly OCUsNotes
80–2,200See ona.com/pricing for current tier options

Consumption order: subscription credits → top-up credits → bonus/gift credits.

Environment runtime

ClassvCPUs / RAMOCU rate
Standard4 vCPUs / 16 GB1 OCU/hour
GPU-accelerated16 vCPUs / 64 GB7 OCUs/hour

fork-sync-all agent sessions run on Standard environments. A 2-hour session costs 2 OCUs in runtime before any model inference.


Agents used in this repo

AgentWhere usedBilling modelContext window
Ona Agent (Claude 4 Sonnet)Interactive sessions, PRs, automationsOCUs (env + model)200K tokens
Codex (via Ona, Core plan)Ona Cloud environmentsOCUs (env only if ChatGPT plan connected)128K tokens
GitHub Models — GPT-4ollm.sh, update-readmes.sh, translate-docs.shGitHub Models quota (not OCUs)128K tokens
GitHub Models — GPT-4o-miniresolve-failures.sh, generate-descriptions.shGitHub Models quota (not OCUs)128K tokens
Anthropic API (direct)Optional via ANTHROPIC_API_KEYPay-per-token (Anthropic billing, not OCUs)200K tokens

Billing independence

Ona Agent and Codex (Ona-managed) are billed in OCUs.

Codex with a connected ChatGPT plan: environment runtime is billed in OCUs; model inference is billed by OpenAI against your ChatGPT plan. Ona does not charge OCUs for those model calls.

GitHub Models (llm.sh): uses a separate GitHub Models quota tied to your GH_TOKEN. Does not consume OCUs. Rate limits apply per model tier.

Anthropic API (direct): billed per-token by Anthropic. Does not consume OCUs.


Tokenizer reference

Token counts determine context window usage and, for pay-per-token models, direct API costs.

Claude (Ona Agent / Anthropic API direct)

Anthropic uses a custom BPE tokenizer:

Content typeApprox. tokens
English prose1 token / 4 chars (~750 words per 1K tokens)
Code (Python / JS / bash)1 token / 3–4 chars
YAML / JSON1 token / 3 chars
Shell scripts1 token / 3 chars
Markdown with headers1 token / 4 chars

Context window: 200K input / 8K output (Claude 4 Sonnet).

A full fork-sync-all session reading 10 workflow files (~500 lines each) uses roughly 50K–80K input tokens in context before any tool calls.

GPT-4o / GPT-4o-mini (GitHub Models / Codex)

OpenAI uses the cl100k_base tiktoken tokenizer. Rates are nearly identical to Claude for English and code. Context window: 128K tokens.

Count tokens locally:

pip install tiktoken
python3 -c "
import tiktoken, sys
enc = tiktoken.get_encoding('cl100k_base')
print(len(enc.encode(open(sys.argv[1]).read())), 'tokens')
" path/to/file.yml

Gemini (direct API, if used)

Google SentencePiece tokenizer. Similar rates to GPT-4o for English; slightly fewer tokens for CJK. Context window: 1M tokens (Gemini 1.5 Pro).

Token → OCU conversion (approximate)

Ona does not publish an exact token-to-OCU ratio. Based on Ona's published benchmarks and typical Claude 4 Sonnet pricing:

Ona benchmarkOCUsApprox. tokens consumed
Explain a small codebase1~20K–50K
Explain a large codebase3~80K–150K
Create a new web app4~100K–200K
Add a feature to medium codebase8~200K–400K

Rough conversion: 1 OCU ≈ 25K–50K tokens (input + output combined). Actual OCU consumption depends on environment runtime, tool call overhead, and Ona's internal pricing model.

Anthropic API direct pricing (as of 2026)

If using the Anthropic API directly (not via Ona):

ModelInput (per 1M tokens)Output (per 1M tokens)
Claude 4 Sonnet$3.00$15.00
Claude 3.5 Haiku$0.80$4.00
Claude 3 Opus$15.00$75.00

A typical fork-sync-all session (100K input + 10K output tokens) costs roughly $0.45–$0.60 via direct API — cheaper than OCUs for pure model cost, but without the environment, tooling, and orchestration Ona provides.


fork-sync-all task cost estimates

All figures assume Standard environment (1 OCU/hour) + Ona Agent (Claude). For GitHub Models tasks (llm.sh), OCU cost is environment runtime only.

By task complexity

TaskEnv timeOCUs (env)OCUs (model)Total OCUsUSD equiv.
Quick question / explain one workflow15 min0.250.5–11–1.5$0.25–$0.38
Fix a single bug or validator error20 min0.331–21.5–2.5$0.38–$0.63
Add a new script or include30 min0.52–42.5–4.5$0.63–$1.13
Add a new workflow (single file)45 min0.753–54–6$1.00–$1.50
Multi-file feature (e.g. flush watchdog)90 min1.56–108–12$2.00–$3.00
Large feature + tests + docs + PR2–3 hr2–38–1510–18$2.50–$4.50
Full session (e.g. platform hardening)3–4 hr3–412–2015–24$3.75–$6.00
End-to-end repo update (all outstanding)4–6 hr4–615–2519–31$4.75–$7.75

By specific fork-sync-all operation

OperationAgentTypical OCUsNotes
Merge open PRs + check CIOna1–2Mostly read + gh CLI
Add a registered import entryOna0.5–1Edit JSON + validate
Update AGENTS.mdOna1–2Read context + write
Fix a failing CI checkOna2–5Depends on root cause
Add a new workflow to mirror chainOna4–8New file + config + tests
Full flush lifecycle implementationOna10–15Multi-file, tests, docs, PR
Platform hardening (7 tasks)Ona15–20Research + 16 files + 271 tests
Onboard a new downstream orgOna6–12Config + workflows + validation
Translate READMEs (all languages)GitHub Models GPT-4o0.5–1OCU = env runtime only; model via GH quota
Generate repo descriptionsGitHub Models GPT-4o-mini0.25–0.5OCU = env runtime only
Resolve CI failures (LLM-assisted)GitHub Models GPT-4o-mini0.25–0.5OCU = env runtime only

GitHub Models quota (separate from OCUs)

llm.sh and the scripts that use it consume GitHub Models quota, not OCUs.

ModelTierDaily limit (approx.)
openai/gpt-4oStandard~150K tokens/day
openai/gpt-4o-miniHigh~1M tokens/day

Limits are subject to change — check github.com/marketplace/models. llm.sh handles 429 responses with exponential backoff automatically.


Budgeting by role

Occasional contributor (1–2 sessions/month)

40 OCU ($10) top-up covers:

  • ~5–8 small bug fixes or single-workflow additions
  • ~2–3 medium features
  • ~1 large feature session

Regular contributor (weekly sessions)

100 OCU ($25) top-up or Core subscription with 200+ OCUs/month:

  • ~10–15 medium tasks/month
  • ~4–6 large feature sessions/month
  • Comfortable headroom for exploratory sessions

Maintainer (daily work, full repo updates)

400 OCU ($100) top-up or Core subscription with 400+ OCUs/month:

  • Weekly full sessions (~20 OCUs each → ~80 OCUs/month)
  • Buffer for unexpected complexity
  • Recommended for anyone running critical-deploy-all or full flush pipelines alongside agent sessions

Auto top-up

Enable auto top-up at Settings → Billing with a 40 OCU trigger threshold. A session interrupted mid-task and restarted from scratch costs more than the top-up itself — context has to be rebuilt from zero.


Cost tracking

This repo includes a workflow and structured log for tracking actual agent costs over time. As observed data accumulates, it replaces the code-audit estimates above.

Log a session

After any significant agent session, run:

# Ona Agent session
gh workflow run track-agent-costs.yml \
  --field task_description="Add flush-active-watchdog + pipeline-guard" \
  --field agent="ona" \
  --field session_hours="3.5" \
  --field ocu_estimate="18" \
  --field pr_number="166"

# GitHub Models session (no OCU model cost)
gh workflow run track-agent-costs.yml \
  --field task_description="Translate READMEs to 5 languages" \
  --field agent="github-models-gpt4o" \
  --field session_hours="0.5" \
  --field ocu_estimate="0.5" \
  --field gh_models_tokens="45000"

# Codex with ChatGPT plan (env OCUs only)
gh workflow run track-agent-costs.yml \
  --field task_description="Refactor sync-all-forks.sh" \
  --field agent="codex-chatgpt" \
  --field session_hours="1.0" \
  --field ocu_estimate="1.0"

# Direct Anthropic API (no OCUs)
gh workflow run track-agent-costs.yml \
  --field task_description="Code review via direct API" \
  --field agent="anthropic-direct" \
  --field session_hours="0.25" \
  --field ocu_estimate="0" \
  --field anthropic_input_tokens="32000" \
  --field anthropic_output_tokens="2000"

View the log

cat data/agent-cost-log.json | python3 -m json.tool

# Summary by agent
python3 -c "
import json
from collections import defaultdict
log = json.load(open('data/agent-cost-log.json'))
totals = defaultdict(lambda: {'sessions': 0, 'ocu': 0.0, 'hours': 0.0})
for e in log['sessions']:
    a = e['agent']
    totals[a]['sessions'] += 1
    totals[a]['ocu'] += e.get('ocu_estimate', 0)
    totals[a]['hours'] += e.get('session_hours', 0)
for agent, t in sorted(totals.items()):
    print(f'{agent}: {t[\"sessions\"]} sessions, {t[\"ocu\"]:.1f} OCUs, {t[\"hours\"]:.1f} hrs')
"

Machine-readable profiles

config/agent-cost-profiles.yml contains the cost profiles used by the tracking workflow for validation and per-agent reporting. Update it as observed data replaces estimates.


GitHub API quota vs OCU budget

These are independent resources:

ResourceUnitLimitManaged by
GitHub REST APIrequests5,000/hr per userquota-reserve.sh, queue-manager.sh
GitHub Modelstokensvaries by modelllm.sh (backoff on 429)
Ona OCUscompute unitssubscription + top-upsOna billing
Anthropic APItokenspay-per-tokenAnthropic billing

GitHub API exhaustion pauses the agent session but does not consume OCUs. OCU exhaustion stops the session regardless of GitHub quota state.

See DOCS/OPERATIONS.md and DOCS/quota-costs.md for GitHub API quota management.


Keeping this document current

  • OCU pricing: verify at app.gitpod.io/settings/billing. The $0.25/OCU top-up rate has been stable since launch but may change.
  • Model: Ona Agent currently uses Claude 4 Sonnet. If the underlying model changes, update the tokenizer section.
  • Anthropic pricing: verify at anthropic.com/pricing. Prices change with new model releases.
  • Task estimates: once ≥10 sessions are logged in data/agent-cost-log.json, replace the code-audit estimates in the tables above with observed p50/p95 values.
  • GitHub Models limits: check github.com/marketplace/models — daily quotas change as the service matures.

OTA Update System

The OTA (over-the-air) system delivers workflow and script updates from fork-sync-all to forks that have opted in. It is the mechanism by which downstream forks stay current without manual merges.


Concepts

UpstreamInterested-Deving-1896/fork-sync-all. The source of truth for all OTA payloads.

Fork — any GitHub repo that has forked fork-sync-all and opted in to OTA.

Payload — a diff of files that changed between the fork's pinned_sha and the latest upstream release tag. Only files the fork hasn't locally modified are included.

Registryconfig/ota-registry.yml. The list of all opted-in repos.

Blocklistconfig/ota-blocklist.yml. Orgs and namespaces excluded from OTA by default (the three mirror-chain orgs and the GitLab namespace).


Lifecycle

Fork owner runs ota-opt-in
        │
        ▼
.ota/config.yml created in fork
Registration PR opened against fork-sync-all
        │
        ▼
PR merged → repo added to config/ota-registry.yml
        │
        ▼
ota-discover.yml (daily) also finds new opt-ins automatically
        │
        ▼
Semver tag pushed to fork-sync-all (v*.*.*)
        │
        ▼
ota-release.yml assembles payload per opted-in repo
Opens PR in each fork with the diff
        │
        ▼
Fork owner merges PR
ota-self-update.yml (runs in fork on schedule) updates pinned_sha

Workflows

ota-opt-in.yml — fork owner runs this once

Propagated to forks via the standalone template profile. The fork owner triggers it via workflow_dispatch. It:

  1. Creates .ota/config.yml in the fork with sensible defaults
  2. Opens a registration PR against fork-sync-all/config/ota-registry.yml

Inputs:

InputDescriptionDefault
upstream_overrideOverride the upstream source (for fork-of-fork cases)(auto-detected)
mirror_chain_opt_inSet true if the fork is in the mirror chainfalse

ota-discover.yml — runs daily in fork-sync-all

Scans GitHub for forks of fork-sync-all that contain .ota/config.yml with enabled: true. For any not already in config/ota-registry.yml, opens a PR to add them.

This is the passive discovery path — fork owners don't need to run ota-opt-in if they create .ota/config.yml manually.

Inputs:

InputDescriptionDefault
dry_runReport new opt-ins without updating registry or opening PRfalse

ota-release.yml — triggered on semver tag push

Triggered when a tag matching v*.*.* is pushed to fork-sync-all. It:

  1. Iterates all repos in config/ota-registry.yml (skipping disabled: true)
  2. For each repo, calls ota-payload-build.sh to assemble the diff
  3. Opens a PR in the fork with the payload
  4. Updates CHANGELOG.md in fork-sync-all

Repos in the blocklist orgs are skipped unless mirror_chain_opt_in: true is set in their .ota/config.yml.


ota-self-update.yml — runs in the fork on a schedule

Propagated to forks via the standalone template profile. Runs on a schedule in the fork. It:

  1. Checks the latest OTA release tag from fork-sync-all
  2. Compares against the fork's pinned_sha in .ota/config.yml
  3. If behind, applies the payload and updates pinned_sha and pinned_at

This is the self-healing path — if a fork owner doesn't merge the OTA PR, ota-self-update will eventually apply the update automatically.


Payload assembly

scripts/ota-payload-build.sh assembles the payload for a single fork:

  1. Detects the fork's upstream parent via GitHub API (or uses upstream_override)
  2. Diffs the fork's current state at pinned_sha against the latest upstream tag
  3. Filters out:
    • Files listed in the fork's exclude_paths
    • Files the fork has locally modified (detected by comparing against upstream)
    • Files owned by template profiles (from config/template-manifest.yml) unless explicitly claimed via workflow_overrides.claim
  4. Applies workflow_overrides.disclaim to remove any files the fork wants to manage independently

The result is a minimal set of files that are safe to overwrite in the fork.


.ota/config.yml reference

Created in the fork by ota-opt-in.yml. All fields except enabled and repo are optional.

enabled: true                  # master switch
repo: "owner/repo-name"        # must match actual GitHub repo
host: "github"                 # "github" only currently
upstream_override: ""          # override upstream detection (fork-of-fork)
pinned_sha: ""                 # managed by ota-self-update — do not edit
pinned_at: ""                  # managed by ota-self-update — do not edit
ota_version: ""                # managed by ota-self-update — do not edit
mirror_chain_opt_in: false     # set true only for mirror-chain repos
workflow_overrides:
  claim: []                    # workflows OTA should manage even if in manifest
  disclaim: []                 # workflows OTA should NOT touch
exclude_paths: []              # glob patterns OTA never writes
include_paths: []              # re-include after exclude_paths

Full field documentation: .ota/schema.yml in this repo.


Blocklist

config/ota-blocklist.yml defines two guards applied before any delivery:

Guard 1 — org/namespace blocklist: The three mirror-chain GitHub orgs (Interested-Deving-1896, OpenOS-Project-OSP, OpenOS-Project-Ecosystem-OOC) and the GitLab namespace (openos-project) are excluded by default. A repo in these orgs can still receive OTA by setting mirror_chain_opt_in: true.

Guard 2 — profile filter: Only repos using the standalone template profile are eligible for OTA. Repos on core, extended, or other profiles are managed by sync-template.yml instead.


Adding a fork to the registry manually

If ota-opt-in is unavailable or the fork owner prefers manual registration:

  1. Create .ota/config.yml in the fork (copy from .ota/schema.yml, set enabled: true and repo)
  2. Add an entry to config/ota-registry.yml:
opted_in:
  - repo: owner/fork-name
    host: github
    registered_at: "2026-06-07"
    pinned_sha: ""
    discovery: false
    mirror_chain_opt_in: false
    disabled: false
  1. Open a PR against fork-sync-allvalidate-config.yml will check the entry.

Disabling OTA for a repo

Set disabled: true in the registry entry. The repo stays registered but receives no further deliveries until re-enabled. Alternatively, set enabled: false in the fork's .ota/config.ymlota-discover will stop treating it as opted-in.

To remove permanently: delete the entry from config/ota-registry.yml.

Workflow Reference

All workflows in .github/workflows/, grouped by priority tier. For trigger details and schedules see Workflow Triggers.

Auto-generated on 2026-07-03 from config/workflow-quota-costs.yml and config/workflow-priority-tiers.yml.

Quota cost columns: Low = fast/cached run · Mid = typical (p50) · High = large/uncached (p95)


Tier 1 — Critical

WorkflowSynopsisSchedulemin_quotaLowMidHigh
Cancel Runs After Token RotationCancels any queued or in-progress workflow runs immediately after token rotation to prevent runs using the old token.Manual5051530
Cancel Stale RunsCancels queued and in-progress workflow runs older than MAX_AGE_MINUTES (default 90) or created before a fix commit, preventing stale runs from burning quota.Manual100103080
Critical DeployFast-lane workflow for deploying critical fixes when the system is degraded — commits and pushes changes, clears the queue aggressively, then dispatches priority workflows.Manual50530100
Critical Deploy — AllFast-lane critical deploy across all four platforms (Interested-Deving-1896, OSP, OOC, GitLab) in sequence. Cost is approximately 4× the single-org variant.20020120400
Critical Deploy — OOCFast-lane critical deploy scoped to OpenOS-Project-Ecosystem-OOC — same three-phase pattern as Critical Deploy but targets the OOC mirror org only.Manual50530100
Critical Deploy — OSPFast-lane critical deploy scoped to OpenOS-Project-OSP — same three-phase pattern as Critical Deploy but targets the OSP mirror org only.Manual50530100
Flush Active WatchdogClears FLUSH_ACTIVE=false whenever Flush Lifecycle Manager or any critical-deploy workflow completes. Prevents stuck-mutex after force-cancel.Manual10123
Flush Lifecycle ManagerCoordinates the three-stage flush pipeline with quota reservation, runner slot holding via a parallel sentinel job, and pause/resume at quota reset windows. Sets FLUSH_ACTIVE=true so queue-manager and quota-reserve protect flush stages.Weekly Sun 06:00 UTC1500154080
GitLab Critical DeployFast-lane GitLab mirror recovery. Pushes current HEAD directly to GitLab via HTTPS, cancels pending pipelines, pauses/resumes schedules, and optionally triggers a fresh pipeline. Works even when GitHub quota is near 0.503815
Mirror WatchdogTriggers when any mirror workflow fails — waits 5 minutes then retries once. Surfaces persistent failures in the Actions tab without consuming quota on repeated retries.Manual5051530
PR GateRequired status check for incoming PRs. Checks quota remaining and posts a comment if the system is degraded. Two rate_limit calls per run.On push10224
Pre-Flush PrepPrepares the system for a clean full-chain-flush — cancels stale runs, merges ready PRs, validates config, cleans merged branches, removes template pollution, then dispatches full-chain-flush when quota is sufficient.Manual1500103060
Queue ManagerDeduplicates queued workflow runs (keeps newest per workflow) and evicts runs queued longer than STALE_QUEUE_MIN (default 25 min) to prevent quota exhaustion cascades.Every 30 min5051530
Quota MonitorPolls GitHub quota and optionally dispatches a target workflow once quota recovers above a configurable threshold. Dispatch-only — never scheduled.101510
Quota ReserveCancels low-priority queued runs when remaining quota drops below RESERVE_FLOOR (default 1000). Uses per-workflow min_quota from workflow-quota-costs.yml for cost-aware cancellation.Every 30 min101515
Rate-Limit Re-triggerScans recently-failed workflow runs, identifies those that failed due to rate limiting, and re-triggers them after their quota reset epoch.Every 4h at :055052050
Rotate Secret TokenRotates GitHub PATs and GitLab tokens stored as org/repo secrets. Validates the new token before committing, then triggers Cancel Runs After Token Rotation to clear stale runs.Manual5051020
Token Health MonitorChecks expiry dates for all tracked PATs and GitLab tokens. Opens a GitHub issue labelled token-monitor when any token expires within 45 days.Weekly Mon 09:24 UTC5051020
Validate ConfigValidates all config files (gitlab-subgroups.yml, workflow-sync.yml, priority-tiers.yml, registered-imports.json) on every push that touches them. Blocks merges on invalid config.Manual502510

Tier 2 — High

WorkflowSynopsisSchedulemin_quotaLowMidHigh
Add Mirror RepoAdds a new repo to the three-org mirror chain (Interested-Deving-1896 → OSP → OOC) by creating the repo in each org, setting up webhooks, and registering it in gitlab-subgroups.yml.Manual200103060
DwarFS Pack ReleasePackages a DwarFS release artifact when an upstream release completes.Manual10051530
Full Chain FlushOrchestrates the complete mirror chain in sequence — mirror-to-osp → mirror-osp-to-ooc → mirror-osp-to-gitlab — with quota checks between each stage.17 5 1 * *10001004001000
Git Platform SyncAgnostic git platform sync. Replaces sync-to-gitlab.yml (direction=push) and sync-from-gitlab.yml (direction=pull). Supports GitHub, GitLab, Gitea, Forgejo, Codeberg as source or destination.Daily 09:23 UTC10052560
Import RepositoryPlatform-agnostic repo importer — clones any public or authenticated git URL into Interested-Deving-1896, optionally mirrors through the OSP→OOC chain and registers for ongoing sync.100103060
Merge Repos into MonorepoMerges multiple git repositories into a single monorepo, preserving full commit history, tags, and Git LFS objects. Manual dispatch only.Manual100103060
Mirror Chain DispatchAgnostic mirror-chain backend. Dispatch-only on canonical instance — dedicated mirror workflows own schedules. Downstream forks without dedicated workflows may add a schedule.1200550800
Mirror Interested-Deving-1896 → OSPBare-clones every repo in Interested-Deving-1896 and git push --mirror into OpenOS-Project-OSP, syncing all branches, tags, and refs exactly.Every 6h at :135002080200
Mirror OSP → GitLabMirrors every repo in OpenOS-Project-OSP to its GitLab counterpart under openos-project, creating the GitLab project in the correct subgroup if it does not exist yet.Daily 01:23 UTC30052050
Mirror to OpenOS-Project-Ecosystem-OOCBare-clones every repo in OpenOS-Project-OSP and git push --mirror into OpenOS-Project-Ecosystem-OOC, completing the second hop of the three-org mirror chain.Every 6h at :453002080200
Mirror to OpenOS-Project-OSPMirrors Interested-Deving-1896 repos to OpenOS-Project-OSP on schedule and push.0 * * * *50050200500
PR Lifecycle GuardReusable quota + queue pre-flight called by PR-creating workflows (OTA Release, Upstream PRs, Rebase PRs). One rate_limit call plus optional queue-manager pass.503820
Pin Workflow ActionsPins GitHub Actions uses references to exact SHA commits via ratchet.Weekly Tue 05:00 UTC1001050150
Pre-Mirror CI GateChecks CI status on all OSP-bound repos in Interested-Deving-1896 before mirroring. Dispatches resolve-failures for red repos, waits, then re-checks. Blocks the mirror if repos are still failing.Manual80050150300
Rebase PRsRebases open PRs in Interested-Deving-1896 onto their base branch when they fall behind, keeping PRs mergeable without manual intervention.10 5 */2 * *10052050
Sync All ForksSyncs all branches of every fork owned by Interested-Deving-1896 with their upstream via the GitHub merge-upstream API, falling back to force-reset on divergence.Daily 06:07 UTC50050200500
Sync Registered ImportsRe-syncs all repos listed in registered-imports.json — bare-clones each source URL and pushes all branches and tags to Interested-Deving-1896.Daily 04:55 UTC20051530
Sync from GitLabDEPRECATED. Superseded by Git Platform Sync (direction=pull). Stub kept for backwards compatibility.Manual100000
Sync to GitLab VariantVariant of Sync to GitLab that uses a different token and push strategy — used when the primary sync is blocked or for testing.Daily 01:50 UTC10052050

Tier 3 — Medium

WorkflowSynopsisSchedulemin_quotaLowMidHigh
Audit Arch ReposWeekly audit of expected vs actual repos across Interested-Deving-1896. Reports missing, unexpected, and mismatched repos to the step summary.Weekly Mon 04:00 UTC10052050
Auto-merge PRsMerges open PRs once required checks pass. Hybrid auto-detection per PR: scope (label/bot/all), strategy (rebase/squash/merge), mechanism (native auto-merge vs poll).Every 6h at :5530053080
BDFS Dev WorkspaceCreates and manages mutable dev workspaces on top of immutable filesystem roots using the bdfs framework (btrfs, overlay, or dwarfs backends). Actions: create, drop, list, commit, status.Manual0000
BDFS Dev — BTRFS BackendCreates a writable BTRFS snapshot of a source subvolume as a bdfs dev workspace. Source must be on a BTRFS filesystem.Manual0000
BDFS Dev — DwarFS BackendMounts a DwarFS image read-only as the lower layer of an overlayfs workspace, with a writable upper layer (BTRFS subvolume or tmpfs).Manual0000
BDFS Dev — Overlay BackendCreates an overlayfs workspace with a source path as the read-only lower layer and tmpfs or a directory as the writable upper layer. Works on any filesystem.Manual0000
Bootstrap TriggersOne-shot self-destruct workflow that fires pending workflow_dispatch triggers on push.Manual502510
Build (self-hosted)Builds the project on a self-hosted runner.Manual20125
Build ARM64Builds the project for ARM64 architecture.Manual20125
Build x86-64Builds the project for x86-64 architecture.Manual20125
CIRuns CI checks on push and pull request events.On push20125
Check AccessibilityMulti-layer accessibility audit — CODEOWNERS coverage, README screen-reader scan, WCAG 2.1 AA HTML check, audio overview (espeak-ng), and Braille output (liblouis). Commits README.audio.mp3 and README.brl artifacts.Weekly Mon 04:17 UTC50051540
Check CI StatusAgnostic CI status checker. Runs check-ci.sh for each enabled target in config/ci-check-targets.yml (GitHub orgs and GitLab groups).Daily 09:05 UTC30050300900
Check OOC CI StatusDaily check of CI status on the default branch HEAD for every OOC-bound repo. Reports failing repos to the step summary.Daily 06:30 UTC50050150300
Check Shell Tools CIBatch-fetches CI run status for all 24 shell-tools repos via a single GraphQL query. Minimal quota cost. Weekly Monday 06:30 UTC.Weekly Mon 06:30 UTC50123
Cleanup Stale BranchesDeletes branches that have been merged into the default branch across all repos in Interested-Deving-1896, OSP, and OOC.29 4 1 * *2001060200
Cleanup Template PollutionRemoves files incorrectly propagated from fork-sync-all to consumer repos via the template sync pipeline, across all three GitHub orgs and GitLab.Manual2002080200
Clone OrgClones all repositories from an org or user on any supported platform (GitHub, GitLab, Bitbucket, Gitea) into Interested-Deving-1896.Manual2002080200
Create Missing READMEsCreates README.md from the standard template for OSP-bound repos that have no README, with placeholder sections for human-owned content.Daily 07:08 UTC2002080200
Delete Stale ReposOne-shot cleanup of superseded repos across GitHub orgs and GitLab. Manual dispatch only.Manual502620
Deploy BookBuilds the mdBook documentation site from DOCS/ and deploys it to GitHub Pages at interested-deving-1896.github.io/fork-sync-all/.Manual5051020
Devcontainer SDKValidates devcontainer.json, features, and automations templates. Optionally builds and pushes the devcontainer image or publishes features to GHCR.Manual500520
Docker → Incus MigrationScans repos for Docker artifacts (Dockerfile, docker-compose.yml) and replaces them with Incus equivalents. Runs after Add Mirror Repo and weekly.Weekly Sun 03:08 UTC1001040100
Enforce Agnostic VendorScans vendor/ for distro-specific hardcoded fallback values in shell, YAML, and TypeScript. All vendored components must be deployment-agnostic.Manual502510
FSA APIFSA API server lifecycle and adapter dispatch. Validates config, smoke-tests server startup, or calls individual adapters directly via workflow_dispatch.Manual20021030
Fork KDE Neon ReposOne-shot workflow that clones the 6 KDE Invent neon repos into Interested-Deving-1896 and pushes them through the OSP mirror chain. Ongoing re-sync handled by sync-registered-imports.Manual100103060
Full AuditWeekly structural audit of workflows, scripts, config registries, assets, and vendor dirs. No REST calls.Weekly Mon 04:00 UTC50000
Generate Book PagesRegenerates DOCS/generated/ pages from config sources (workflow-quota-costs.yml, priority-tiers.yml, gitlab-subgroups.yml, registered-imports.json) and commits the result.Manual50125
Generate Repo DescriptionsAI-powered per-file description generator. Fetches file tree (1 REST call) then reads each file for context (1 REST call per file) before calling GitHub Models. Cost scales with MAX_FILES setting.Weekly Sun 03:30 UTC30020100300
HW Detect CIRuns CI for hardware detection tooling on schedule and push.Weekly Mon 06:00 UTC502515
Inject Built-with-Ona BadgesAdds a Built-with-Ona badge to README.md for all repos in Interested-Deving-1896 that are missing it. Skips repos that already have the badge.15 8 */2 * *20053080
List Active RunsLists all active workflow runs with clickable web and API URLs.Every 30 min50235
Manage Repo SettingsDeclarative repo settings drift detection and enforcement. Check mode reads current state (1 REST call per repo) and reports drift. Apply mode patches drifted fields (1-3 REST calls per drifted repo).Weekly Mon 04:30 UTC2001060150
Merge Ready PRsWaits for CI then merges all open PRs with passing checks across fork-sync-all and btrfs-dwarfs-framework.Manual2001040100
Mirror Flatpak RepoBuilds and publishes a self-hosted Flatpak repo on GitHub Pages. Downloads Flatpak bundles from OSP/OOC releases and imports them into the org flatpak-repo.Daily 05:00 UTC3002060150
Mirror GHCR ImagesRe-tags and pushes GHCR container images from an upstream owner into OSP and OOC orgs. Daily schedule.Daily 03:00 UTC2001040100
Mirror PyPI PackagesRe-publishes PyPI packages from upstream repos to OSP/OOC with org-prefixed package names (e.g. osp-linux-kernel-manager).Manual10052060
Mirror RPM RepoMirrors RPM packages from OSP/OOC releases to a self-hosted RPM repo on GitHub Pages. Daily schedule.Daily 04:30 UTC2001040100
OTA DiscoverScans forks of fork-sync-all for .ota/config.yml with enabled: true and adds newly discovered repos to config/ota-registry.yml.Daily 06:38 UTC1001040100
OTA Opt-InPropagated to opted-in forks. Fork owners run this once to create .ota/config.yml and open a registration PR against fork-sync-all's OTA registry.5051530
OTA ReleaseTriggered on semver tag push. Assembles and delivers OTA updates to all opted-in repos in config/ota-registry.yml, then updates CHANGELOG.md with release notes.Manual1001040100
OTA Self-UpdatePropagated to opted-in forks. Pulls the latest OTA release from fork-sync-all and applies it to the fork's workflow files.Weekly Mon 05:15 UTC5051530
Onboard BugzillaGuided one-time setup: validates Bugzilla connectivity, creates product/components, writes config/bugzilla.yml.Manual10051530
Onboard RepositoryOnboards new repos into the ecosystem — applies labels, branch protection, topics, description, welcome issue, and dispatches sync-template/setup-osp-mirrors/sync-registered-imports.Manual2002060150
Org Storage MaintenanceWeekly GitLab storage housekeeping across openos-project: triggers artifact expiry and deletes old generic package versions older than 90 days (keeps 5 per package).Weekly Sun 02:00 UTC0000
PR AutomationApplies size labels, path-based labels, reviewer auto-assignment, risky pattern detection, and auto-merge for low-risk PRs on every PR open or update.On push5051530
Pin ManagerManages version pinning, GitHub profile pins, and repo issue pins.Weekly Mon 06:00 UTC15031025
Pipeline TelemetryPost-run observability workflow. Fetches completed run data, builds a span tree (workflow→jobs→steps), computes Thoth-equivalent metrics, parses log severity, writes a step summary and trace artifact, and upserts a rolling metrics issue.Manual20051530
Post-Flush VerificationEnd-to-end health check after full-chain-flush — mirror integrity across all three pairs, CI status on I-D-1896 OSP-bound repos, quota health, and workflow queue health.Manual300150350600
Provision GitLab Maintenance SchedulesPushes .gitlab/scheduled-maintenance.yml and creates a weekly maintenance schedule on every actively developed project under openos-project. Safe to re-run.0000
Push Kernel ContentPushes kernel version metadata (READY, VERSION, config/, patches/, README.md) to the debian-{arch}-kernel-base repos (one per arch, up to 10).Manual100103080
Rebuild LTS Branch (penguins-eggs)Rebases the all-features branch onto the upstream master after each pieroproietti sync, then force-pushes the result to the lts branch.Manual5051530
Reconcile Identity AssetsDetects the current FSA instance, selects the matching brand variant, writes active assets to assets/brand/.active/, and injects identity content into DOCS/cover.md.Manual10135
Reconcile Org ReferencesRewrites org/repo references in OSP and OOC mirrors to point at the correct org, fixing stale Interested-Deving-1896 references left by the mirror process.50 5 */2 * *3001060150
ReleaseCreates a GitHub release and uploads build artifacts on tag push.Manual10051530
Resolve CI FailuresAnalyses CI failure patterns across OSP-bound repos and applies automated fixes (dependency updates, config corrections, workflow patches) where possible.Daily 07:43 UTC1001040100
Resolve CI Failures (Agnostic)Agnostic CI failure resolver. Runs resolve-ci.sh for each enabled target in config/ci-check-targets.yml. GitHub targets use LLM analysis and auto-fix; GitLab targets retry failed/canceled pipelines.Daily 07:43 UTC10010120400
Runner StatusReports runner utilisation and queue depth across the org. Flags workflows with queue depth above configurable warn/critical thresholds.Every 1h at :1050248
Seed Patchset BranchesSeeds 9 patchset branches per debian-{arch}-kernel-base repo for Debian (trixie/forky/sid), Devuan (excalibur/forky/ceres), and Ubuntu (resolute/stonking/devel).Manual2002060150
Setup Dashboard VariablesSets all VITE_* repository variables required by the infra-dashboard public-dashboard build. Safe to re-run — blank inputs leave existing variables unchanged.Manual5051530
Setup OSP Mirror WorkflowsEnsures all repos in OpenOS-Project-OSP have the correct mirror workflow files and secrets configured for the OSP→OOC mirror chain.Daily 02:45 UTC2002080200
Sync FSA ForksKeeps downstream fork-sync-all forks in sync with upstream. Opens PRs on drift.Daily 04:00 UTC20052060
Sync KDE Groups MirrorsSyncs all KDE group mirror repos under openos-project/kde-ecosystem-deving/kde-groups from invent.kde.org. Daily schedule.Daily 01:00 UTC3002080200
Sync KDE Neon MirrorsSyncs all KDE Neon mirror repos in openos-project/kde-ecosystem-deving/neon-deving from invent.kde.org/neon/. Daily schedule, offset 30 min from Sync KDE Groups Mirrors.Daily 01:30 UTC3002080200
Sync Pieroproietti GitLab ForksSyncs the three pieroproietti GitLab forks (penguins-eggs, penguins-eggs-book, oa-tools) from their GitHub upstreams. Mirrors branches, tags, and creates GitLab Releases for new tags.Daily 02:15 UTC10051540
Sync Registry BackendAgnostic registry sync backend propagated to upstream-sync consumers. Dispatch-only, no schedule, no hardcoded defaults. Reads vars.AF_REGISTRY_REPO / AF_REGISTRY_BRANCH / AF_REGISTRY_PATH for self-configuration.1001040100
Sync Registry SourcesRegistry-driven upstream sync (central orchestrator) — reads a JSON registry of upstream sources and syncs each repo via merge-upstream or force-reset. Runs daily from fork-sync-all with penguins-eggs defaults.Daily 03:05 UTC1001040100
Sync Shell Tools VendorSparse-clones each of the 24 shell-tools forks and copies entrypoint scripts into vendor/shell-tools/. One clone per tool (~2 REST calls each via git protocol). Weekly Sunday 02:00 UTC.Weekly Sun 02:00 UTC300244872
Sync TemplateSyncs fork-sync-all's file tree into target repos. Three modes — create (new repo + mirror chain), inject (copy into existing repo), propagate (push-triggered sync to all consumers in template-consumers.yml).Manual2002080200
Sync UAA VendorSyncs vendor/unified-agnostic-api from Interested-Deving-1896/unified-agnostic-api via sparse checkout. Runs on push to vendor/unified-agnostic-api/** or weekly schedule.Weekly Tue 05:00 UTC10051530
Sync Upstream Mirrors (GitLab)Syncs all upstream mirror repos in openos-project/upstream-mirrors from their original GitHub sources. Daily schedule.Daily 00:00 UTC2001040100
Sync Upstream SourcesReads the Origins section of every OSP-bound repo and syncs each referenced external fork to its upstream HEAD via merge-upstream or force-reset.Daily 01:37 UTC2002080200
Sync btrfs-devel BranchesSyncs tracked btrfs-devel branches from the upstream kernel tree into the btrfs-dwarfs-framework fork.Daily 05:02 UTC10052050
Sync pieroproietti ForksSyncs all penguins-eggs forks owned by Interested-Deving-1896 with their upstream pieroproietti sources via merge-upstream.Daily 01:07 UTC1001040100
Sync to GitLabDEPRECATED. Superseded by Git Platform Sync (direction=push). Stub kept for backwards compatibility.Manual100000
Sync-inManages Sync-in server/client lifecycle. Server role: health-check, deploy, token rotation. Client role: register OSP-bound repos as workspaces, trigger syncs. Scheduled health every 6h, workspace sync daily.Every 6h at :375022080
Trigger README Update (All Repos)Dispatches update-readmes.yml for all OSP-bound repos in batch. Use after a rate-limit reset to propagate README updates org-wide.Manual200103080
Update READMEsRegenerates AI-owned sections (what-it-does, architecture, ci, mirror-chain, etc.) in README.md for all OSP-bound repos, preserving human-owned sections.Daily 03:15 UTC30050150300
Upload AssetUploads files from URLs, artifacts, or repo paths to a release, repo directory, or issue comment.Manual502515
Upload NotebookLM AssetsUploads NotebookLM generated output files (audio, PDF) to a GitHub Release. Creates the release if it does not exist yet.Manual502510
Upstream Contribute (caller)Consumer-repo caller for upstream-contribute.yml. Analyses push diff and opens upstream PRs.Manual5021020
Validate README RenderChecks README.md for rendering issues — leaked log lines, unclosed fences, bare brackets, raw angle brackets, unclosed AI markers, missing H1, and empty sections.Manual5051530
Verify Fork IntegrityCompares this repo's default-branch HEAD against its upstream parent (or upstream_override from .ota/config.yml). Reports sync status; configurable hard-fail on drift.Weekly Mon 06:25 UTC100358
Verify Mirror IntegrityCompares default-branch HEAD SHAs between source and destination for all OSP-bound repos after a mirror stage. Reports mismatches as warnings; configurable hard-fail mode.Manual40050100150
Vouch Check PRHybrid A/B/C PR trust gate. Reads VOUCHED.td and changed file paths to select response — denounced authors auto-closed, unknown authors touching sensitive paths blocked, unknown authors on safe paths warned only.303820
Vouch ManageManages contributor vouch status via issue/PR comments. Maintainers use vouch/unvouch/denounce commands; changes are applied via auto-opened PRs against VOUCHED.td.Manual202510
bdfs PackagePackages fork-sync-all as a bdfs workspace (DwarFS + BTRFS).Manual50125

Tier 4 — Low

WorkflowSynopsisSchedulemin_quotaLowMidHigh
Accessibility PR GateAccessibility gate on pull requests. Blocks merge if accessibility violations are found.0000
Bootstrap OrgOne-shot org bootstrap: fork fork-sync-all into a new org, substitute config, set secrets, dispatch post-bootstrap workflows.Manual100306080
Branch Hygiene ReportReports stale and unmerged branches. Manual dispatch only.Weekly Mon 14:00 UTC0000
Bugzilla Failure ReporterFiles or updates a Bugzilla bug when a monitored workflow fails; comments on recovery.Manual302510
Bugzilla Milestone ShipMarks Bugzilla target milestone as shipped and notifies resolved bugs when a version tag is pushed.Manual302820
BuildBuilds the project. Triggered on push/PR.Manual0000
Check GitLab CI SyncCompares paired jobs in .gitlab-ci.yml against config/workflow-sync.yml and reports drift — scripts with changed entry points, mismatched cadence rules, or jobs missing from either side.Manual502510
ChecksGeneral checks workflow. Triggered on push/PR.On push0000
Clear All NotificationsMarks all GitHub notifications as read for the authenticated user.Manual50125
CodeQLCodeQL security analysis. Triggered on push/PR/schedule.0000
Create OOC GitLab SubgroupsCreates the GitLab subgroup structure for OpenOS-Project-Ecosystem-OOC and records the resulting subgroup IDs.Manual5052050
Critical Deploy — Stub (template — not functional)Template for new platform critical deploy targets. Non-functional until copied, renamed, and filled in. Update costs when the platform is activated.Manual50530100
Eco AuditAudits fork-sync-all against KDE Eco / Blue Angel DE-UZ 215 criteria. Checks green hosting, CI efficiency, telemetry, dependency footprint. Stubs KEcoLab energy measurement for GitLab activation. Weekly on Sundays.Weekly Sun 05:00 UTC50135
Export Book (Multi-Engine)Exports the book to one or all supported engines (mdBook, MkDocs, Docusaurus, Pandoc). Manual dispatch only.Manual0000
Generate NotebookLM ContentGenerates NotebookLM content artifacts (audio, video, slides, infographic, quiz, flashcards, report) for a given notebook and uploads them to a GitHub Release.Manual5051530
Generate OSP Dependency GraphScans all OSP-bound repos for package.json and requirements.txt files and generates a dependency graph showing inter-repo relationships.Weekly Sun 03:10 UTC1002060150
Generate SBOMFour-stage SBOM pipeline — Trivy generates CycloneDX+SPDX, sbomasm augments metadata, parlay enriches components, sbomqs scores quality. Runs weekly and on push to main. Release assets attached by OTA Release.Weekly Tue 02:41 UTC102510
Generate architecture configGenerates architecture config from org repo metadata.Manual502515
GitBook OSSManages the GitBook OSS (Next.js) renderer. Actions: build, export, update, dev-info. Weekly update check on Mondays.Weekly Mon 04:17 UTC0000
GitLab Storage ScanScans all projects under openos-project on GitLab and reports storage usage. Useful for diagnosing when the namespace approaches its 10 GiB limit.Manual502510
Inject Repo MottoInjects repo motto/slogan into README.md files across all orgs.30 8 */2 * *200530100
Integrate Shell ToolsRuns smoke tests and integration demos for vendored shell-tools. No GitHub API calls — pure runner execution. Weekly Sunday 03:00 UTC (after sync-shell-tools).Weekly Sun 03:00 UTC50125
LTS README StandardisationStandardises README.md structure for LTS-tagged repos, ensuring they follow the LTS template with correct version badges and support tables.19 3 1 * *1001040100
List Chromium GitLab ReposLists all projects under the Chromium_Browser_OS_Deving GitLab group. Informational only — used to audit what has been mirrored.Manual502510
Manage SubtreesKeeps git subtrees, submodules, and umbrella repo relationships current per config/subtree-manifest.yml.Weekly Sun 01:00 UTC50005
Mirror ArtifactsMirrors GitHub Releases, Flatpak packages, and RPM packages from Interested-Deving-1896 repos to their OSP and OOC counterparts.Daily 02:10 UTC2001050150
Mirror OrgsMirrors all repos from Interested-Deving-1896 to OpenOS-Project-OSP and OpenOS-Project-Ecosystem-OOC using bare clone + push --mirror.Daily 02:17 UTC1002060150
Mirror ReleasesMirrors GitHub Releases (tags + release notes + assets) from Interested-Deving-1896 repos to their OSP and OOC counterparts.Every 12h at :032001050150
Notification ManagerHourly notification triage. Auto-marks known-safe patterns (mirror failures, quota artifacts, Dependabot) as read. Supports manual dispatch with list/mark-all-read actions.17 * * * *2001515
Notification PollerPolls GitHub notifications for unread CI failure notifications and triggers resolve-failures immediately when any are found.Every 4h at :32501515
OTA ReconcileWeekly drift detection and quota-fallback reconcile for mirror-chain consumer repos. Autonomously selects path A (stamp), B (drift PR), or C (quota-recovery PR) per repo based on .ota/version SHA, open PR state, and OTA_SYNC_INCOMPLETE variable.Weekly Wed 03:17 UTC2002080200
PR LabelerAutomatically labels pull requests based on changed paths. Triggered on pull_request.50125
README WizardAI-guided README authoring — writes or rewrites a README for a specific repo according to custom instructions (audience, tone, sections), respecting existing human-owned markers.Manual100103060
Rate Limit StatusQueries current rate limit status for all external APIs used by fork-sync-all. On-demand health check.Manual10235
Refresh NotebookLM AuthRotates the short-lived __Secure-1PSIDTS cookie in NOTEBOOKLM_AUTH_JSON weekly and writes the updated state back to the repo secret.Weekly Tue 06:17 UTC10125
Repo ManifestExports a manifest of all repos in an org, or imports repos from a manifest into a target GitHub org. Supports multi-platform bulk import.Manual1001040100
Setup GitLab CI SchedulesReplaces all existing GitLab pipeline schedules in openos-project/ops/fork-sync-all with the 3 consolidated CADENCE-based schedules. Safe to re-run.502510
Shallow Reclone Large GitLab MirrorsReduces GitLab storage usage by replacing full git history on large mirror projects with a shallow clone. Run when openos-project approaches its 10 GiB storage limit.Manual502510
Sync Agent PricesWeekly hybrid A+B+C price refresh for config/agent-cost-profiles.yml. Fetches LiteLLM model_prices_and_context_window.json at a pinned SHA, diffs against current prices, and opens a PR for human review if anything changed. Flags stale manual entries as warnings. Never auto-merges.Weekly Mon 09:00 UTC503815
Sync Ona ProjectsReconciles config/ona-projects.yml with the Ona API. Creates or updates Ona projects for all repos in the org chain. Runs in dry-run mode when ONA_TOKEN is absent.Daily 06:00 UTC501520
Sync penguins-eggs docs to penguins-eggs-bookTriggered by repository_dispatch from penguins-eggs when docs/chromiumos/ changes on all-features. Syncs the updated docs into the penguins-eggs-book repo.Manual5051530
Sync to BugzillaParses commits and PRs for Bug NNN references and updates Bugzilla status and comments.Manual502820
Test Time FormatValidates time_format.py portability across glibc, musl, and BSD libc. Runs on push/PR to time_format.py.Manual0000
Track Agent CostsRecords AI agent session cost estimates (OCUs, USD, tokens) to a structured JSON log. Supports Ona Agent, Codex, GitHub Models, and direct API agents. Builds an observed cost dataset to replace code-audit estimates in DOCS/ai-agent-costs.md over time.Manual10123
Translate DocsTranslates DOCS/ mdBook pages into a target language using GitHub Models API. Writes translated files to DOCS// and upserts a language section in SUMMARY.md.15 11 */2 * *10051530
Translate READMEsTranslates README.md files for OSP-bound repos into additional languages using GitHub Models API. Writes translated files alongside the English original.43 10 */2 * *1001040100
Trigger Artifact MirrorDispatches mirror-artifacts immediately when a release is published in this repo, so OSP and OOC receive the release without waiting for the next scheduled run.Manual502510
Update Book IndexRegenerates DOCS/generated/ pages (source tree, glossary, workflow index) on push to main. Commits with [skip ci].Manual0000
Update Infrastructure DependenciesScans workflow files across the three-org chain for outdated Actions versions, EOL runners, and EOL Node/Python versions, then opens PRs.Weekly Mon 06:11 UTC20050150250
Update Quota Cost RegistryReads quota-instrument records from job logs, computes observed p50/p95 REST costs per workflow, and commits updated values to workflow-quota-costs.yml weekly.Weekly Mon 08:00 UTC2003080150
Update Workflow Triggers DocRegenerates docs/workflow-triggers.md and docs/workflow-triggers.txt whenever a workflow file changes on main. Commits the result directly to main.Manual5051020
Update kde-builder vendorPulls latest kde-builder upstream into vendor/kde-builder/ via git subtree. Manual dispatch only.Manual0000
Upstream Direct Commits from OSP + OOCDetects commits pushed directly to OSP/OOC default branches (without a PR) and opens PRs against Interested-Deving-1896 to reconcile them.Daily 03:47 UTC2002080200
Upstream PRs from OSP + OOCDetects commits on OSP and OOC default branches that are not present in Interested-Deving-1896 and opens PRs to bring them upstream.Daily 03:33 UTC2002080200
Upstream Workflow ProposalScans OSP-bound repos for new workflow patterns not present in fork-sync-all and opens a PR proposing them as template skeletons.Weekly Mon 06:06 UTC5052050
Vouch OnboardOnboards contributors into the vouch registry (admin/self/auto/seed modes). Runs platform verification checks and commits registry + VOUCHED.td changes. Also triggered by vouch-labelled issues.Daily 03:00 UTC3031025
Vouch Sync CodeownersWeekly sync of CODEOWNERS entries and org members into VOUCHED.td via vouch-seed.sh. Opens a PR if VOUCHED.td changed.Weekly Mon 04:23 UTC5051540
btrfs-devel syncWeekly sync of fs/btrfs/ subtree from kdave/btrfs-devel into this repo via git read-tree. Opens a PR when changes are found.Weekly Mon 03:00 UTC50012
opencodeOpenCode AI assistant integration. Triggered on issue/PR comments.0000

✦ Mid value is an observed p50 measurement. All other values are code-audit estimates.

Registered Imports

All 157 upstream repositories tracked in registered-imports.json. These are synced to Interested-Deving-1896 by sync-registered-imports.yml daily at 04:55 UTC.

Auto-generated on 2026-07-03 from registered-imports.json.

GitHub (156)

Target repoSource URLAdded
CI-Debuggerhttps://github.com/Interested-Deving-1896/CI-Debugger2026-06-05
CachyOS-PKGBUILDShttps://github.com/CachyOS/CachyOS-PKGBUILDS2026-06-06
CachyOS-Settingshttps://github.com/CachyOS/CachyOS-Settings2026-06-06
ClaudeEarnSelf-runtimehttps://github.com/relayhop/ClaudeEarnSelf-runtime2026-06-25
New-Cli-Installerhttps://github.com/CachyOS/New-Cli-Installer2026-06-06
OmoiOShttps://github.com/kivo360/OmoiOS2026-06-05
PhoneixAIhttps://github.com/rajshah9305/PhoneixAI2026-06-05
READMEhttps://github.com/canalplus/README2026-06-12
Smart-File-Organizerhttps://github.com/PavaraM/Smart-File-Organizer2026-06-13
User-Filesystemhttps://github.com/andrachiritoiu/User-Filesystem2026-06-13
accessibility-agentshttps://github.com/Community-Access/accessibility-agents2026-06-05
achievementshttps://github.com/nathanielop/achievements2026-06-13
actions-orchestratorhttps://github.com/fjaeckel/actions-orchestrator2026-05-25
activitysmith-github-actionhttps://github.com/ActivitySmithHQ/activitysmith-github-action2026-06-05
agentic-shellhttps://github.com/Flux159/agentic-shell2026-06-13
agentshieldhttps://github.com/affaan-m/agentshield2026-06-05
ai-bomhttps://github.com/Trusera/ai-bom2026-06-13
ananicy-ruleshttps://github.com/CachyOS/ananicy-rules2026-06-06
api-basehttps://github.com/topboyasante/api-base2026-06-13
apibrewhttps://github.com/tislib/apibrew2026-06-13
apifshttps://github.com/rmatsuoka/apifs2026-06-13
apifusefshttps://github.com/scottvr/apifusefs2026-06-13
ashoshttps://github.com/ashos/ashos2026-06-14
axe-corehttps://github.com/dequelabs/axe-core2026-06-12
bash-api-serverhttps://github.com/Lifailon/bash-api-server2026-06-13
bash-ithttps://github.com/Bash-it/bash-it2026-06-13
bashlyhttps://github.com/bashly-framework/bashly2026-06-13
bibhelperhttps://github.com/aplund/bibhelper2026-06-13
blincushttps://github.com/ublue-os/blincus2026-06-14
blueprinthttps://github.com/Narven/blueprint2026-06-05
browser-fs-accesshttps://github.com/GoogleChromeLabs/browser-fs-access2026-06-13
build-serverhttps://github.com/jakwuh/build-server2026-05-25
cachy-chroothttps://github.com/CachyOS/cachy-chroot2026-06-06
cachy-updatehttps://github.com/CachyOS/cachy-update2026-06-06
cachyos-repo-add-scripthttps://github.com/CachyOS/cachyos-repo-add-script2026-06-06
chromium-automationhttps://github.com/quitecode9-lab/chromium-automation2026-06-13
chwdhttps://github.com/CachyOS/chwd2026-06-06
clahubhttps://github.com/DamageLabs/clahub2026-06-05
claude-devcontainer-bootstraphttps://github.com/niabhail/claude-devcontainer-bootstrap2026-06-14
clawmetryhttps://github.com/vivekchand/clawmetry2026-06-05
cluster-api-provider-incushttps://github.com/lxc/cluster-api-provider-incus2026-06-13
confmgrhttps://github.com/chevdor/confmgr2026-06-05
copr-linux-cachyoshttps://github.com/CachyOS/copr-linux-cachyos2026-06-06
coreutilshttps://github.com/uutils/coreutils2026-06-06
cross-platform-system-interactionhttps://github.com/fmartini23/cross-platform-system-interaction2026-06-13
darwinkithttps://github.com/progrium/darwinkit2026-06-13
denoflowhttps://github.com/Interested-Deving-1896/denoflow2026-06-05
devcontainers-clihttps://github.com/devcontainers/cli2026-06-14
devpodhttps://github.com/loft-sh/devpod2026-06-14
directory-modelhttps://github.com/Interested-Deving-1896/directory-model2026-06-05
dirstructxhttps://github.com/Interested-Deving-1896/dirstructx2026-06-05
distroboxhttps://github.com/89luca89/distrobox2026-06-14
distrobuilderhttps://github.com/lxc/distrobuilder2026-06-14
dotdrophttps://github.com/deadc0de6/dotdrop2026-06-05
espeak-nghttps://github.com/espeak-ng/espeak-ng2026-06-12
extensions-taloshttps://github.com/siderolabs/extensions2026-06-14
firecracker-containerdhttps://github.com/firecracker-microvm/firecracker-containerd2026-06-14
fluent-github-actionshttps://github.com/tsirysndr/fluent-github-actions2026-06-05
fswatch-Filesystem-Events-Watchfolder-Shell-Scripthttps://github.com/digitaltvguy/fswatch-Filesystem-Events-Watchfolder-Shell-Script2026-06-13
gavihttps://github.com/homoluctus/gavi2026-06-05
gha-repo-managerhttps://github.com/andrewthetechie/gha-repo-manager2026-06-13
git-queuehttps://github.com/nautilus-cyberneering/git-queue2026-06-08
git-release-shellhttps://github.com/CadmusCJung/git-release-shell2026-06-13
git-repo-managerhttps://github.com/turahe/git-repo-manager2026-06-13
git-repo-worktrees-managerhttps://github.com/hakoerber/git-repo-manager2026-06-13
git-sizerhttps://github.com/github/git-sizer2026-06-07
github-actions-virtualization-supporthttps://github.com/josecelano/github-actions-virtualization-support2026-05-25
github-actions-workflow-tshttps://github.com/emmanuelnk/github-actions-workflow-ts2026-06-05
github-api-scriptshttps://github.com/alexkli/github-api-scripts2026-06-13
github-api-scripts1https://github.com/locus313/github-api-scripts2026-06-13
github-codeownershttps://github.com/kohofinancial/github-codeowners2026-06-12
github-exporterhttps://github.com/githubexporter/github-exporter2026-06-07
graphizehttps://github.com/apvarun/graphize2026-06-05
headroomhttps://github.com/chopratejas/headroom2026-06-02
hrsynchttps://github.com/dparoli/hrsync2026-06-13
incushttps://github.com/lxc/incus2026-06-14
incus-oshttps://github.com/lxc/incus-os2026-06-14
infra-dashboardhttps://github.com/Interested-Deving-1896/infra-dashboard2026-06-04
ipfs-api-mounthttps://github.com/SupraSummus/ipfs-api-mount2026-06-13
ipinfohttps://github.com/niklasberglund/ipinfo2026-06-13
jail-shhttps://github.com/notgiven688/jail-sh2026-06-13
katachihttps://github.com/nmicovic/katachi2026-06-05
kde-atticahttps://github.com/KDE/attica2026-06-17
kde-builderhttps://github.com/KDE/kde-builder2026-06-03
kde-fieldinghttps://github.com/KDE/fielding2026-06-17
kde-kapidoxhttps://github.com/KDE/kapidox2026-06-17
kernel-managerhttps://github.com/CachyOS/kernel-manager2026-06-06
kernel-patcheshttps://github.com/CachyOS/kernel-patches2026-06-06
liblouishttps://github.com/liblouis/liblouis2026-06-12
lifohttps://github.com/lifo-sh/lifo2026-06-13
linux-cachyoshttps://github.com/CachyOS/linux-cachyos2026-06-06
linux-shell-script-archivehttps://github.com/omyldrm/linux-shell-script-archive2026-06-13
llm-docs-generatorhttps://github.com/Interested-Deving-1896/llm-docs-generator2026-06-05
lowlighter-metricshttps://github.com/lowlighter/metrics2026-06-07
mass_clonehttps://github.com/konzy/mass_clone2026-06-13
matrix-lockhttps://github.com/rakles/matrix-lock2026-05-25
mdBookhttps://github.com/rust-lang/mdBook2026-06-07
mist.shhttps://github.com/jsbmg/mist.sh2026-06-13
mkinitcpio-dirhttps://github.com/vadmium/mkinitcpio-dir2026-06-13
mnemonichttps://github.com/Interested-Deving-1896/mnemonic2026-06-05
models-generatorhttps://github.com/Interested-Deving-1896/models-generator2026-06-05
namefixhttps://github.com/pinkorca/namefix2026-06-13
netclawhttps://github.com/automateyournetwork/netclaw2026-06-05
nexa-gaugehttps://github.com/harnexa/nexa-gauge2026-06-05
niko-claude-skillshttps://github.com/nikotsy/niko-claude-skills2026-05-25
notificarehttps://github.com/joaoGabriel55/notificare2026-06-05
nvdahttps://github.com/nvaccess/nvda2026-06-12
omni-taloshttps://github.com/siderolabs/omni2026-06-14
operation-phantom-shellhttps://github.com/Amalzalu/operation-phantom-shell2026-06-13
osarahttps://github.com/jcsteh/osara2026-06-12
pa11yhttps://github.com/pa11y/pa11y2026-06-12
packer-plugin-incuschroothttps://github.com/dontlaugh/packer-plugin-incuschroot2026-06-05
pkgbuild-actionhttps://github.com/CachyOS/pkgbuild-action2026-06-06
portalhttps://github.com/nanopack/portal2026-06-13
project-memory-mcphttps://github.com/Interested-Deving-1896/project-memory-mcp2026-06-05
puppeteerhttps://github.com/Alex313031/puppeteer2026-06-13
pylibsmetahttps://github.com/tushkum34-cloud/pylibsmeta2026-06-05
pyverthttps://github.com/Interested-Deving-1896/pyvert2026-06-05
remote-synchttps://github.com/tchartron/remote-sync2026-06-13
repo-descriptionhttps://github.com/ioncakephper/repo-description2026-06-13
repo-manage-utilhttps://github.com/CachyOS/repo-manage-util2026-06-06
rm-safelyhttps://github.com/zdk/rm-safely2026-06-13
rtkhttps://github.com/kohofinancial/rtk2026-06-13
rugixhttps://github.com/rugix/rugix2026-06-14
scriptfshttps://github.com/Interested-Deving-1896/scriptfs2026-06-05
scx-managerhttps://github.com/CachyOS/scx-manager2026-06-06
shell2httphttps://github.com/msoap/shell2http2026-06-13
shellqueuehttps://github.com/leifdenby/shellqueue2026-06-13
simple-deployhttps://github.com/Vaelatern/simple-deploy2026-06-13
sizeshttps://github.com/sevenreasons/sizes2026-06-13
smartcdhttps://github.com/CodesOfRishi/smartcd2026-06-13
super-yamlhttps://github.com/doriaviram/super-yaml2026-06-05
swap.shhttps://github.com/jogor9/swap.sh2026-06-13
sync-in-desktophttps://github.com/Sync-in/desktop2026-06-15
sync-in-serverhttps://github.com/Sync-in/server2026-06-15
system-cleanup-managerhttps://github.com/Interested-Deving-1896/system-cleanup-manager2026-06-05
taloshttps://github.com/siderolabs/talos2026-06-14
talos-incushttps://github.com/windsorcli/talos-incus2026-06-14
target-size-highlighterhttps://github.com/accessibility-tools/target-size-highlighter2026-06-12
taubytehttps://github.com/Interested-Deving-1896/taubyte2026-06-05
tombhttps://github.com/dyne/tomb2026-06-13
unified-ai-apihttps://github.com/beamitpal/unified-ai-api2026-06-13
utility_shellhttps://github.com/yennanliu/utility_shell2026-06-13
velitehttps://github.com/zce/velite2026-06-05
victoriametrics-metricshttps://github.com/VictoriaMetrics/metrics2026-06-07
webhookhttps://github.com/adnanh/webhook2026-06-13
xml-yaml-json-converterhttps://github.com/Interested-Deving-1896/xml-yaml-json-converter2026-06-05
y2jhttps://github.com/UltiRequiem/y2j2026-06-05
yaml-fusehttps://github.com/Interested-Deving-1896/yaml-fuse2026-06-05
yaml-sorthttps://github.com/Interested-Deving-1896/yaml-sort2026-06-05
yamllint-tshttps://github.com/Keylan/yamllint-ts2026-06-05
z-index-focus-overridehttps://github.com/accessibility-tools/z-index-focus-override2026-06-12
zenfs-archiveshttps://github.com/zen-fs/archives2026-06-13
zenfs-bundlehttps://github.com/zen-fs/bundle2026-06-13
zenfs-corehttps://github.com/zen-fs/core2026-06-13
zenfs-linuxhttps://github.com/zen-fs/linux2026-06-13

GitLab (1)

GitLab Subgroup Map

All 225 OSP-bound repositories mapped to their GitLab subgroup under openos-project. This is the single source of truth used by mirror-osp-to-gitlab.sh.

Auto-generated on 2026-07-03 from config/gitlab-subgroups.yml.


accessibility_deving

RepoGitHubGitLab
READMEGitHubGitLab
axe-coreGitHubGitLab
espeak-ngGitHubGitLab
liblouisGitHubGitLab
nvdaGitHubGitLab
osaraGitHubGitLab
pa11yGitHubGitLab
target-size-highlighterGitHubGitLab
z-index-focus-overrideGitHubGitLab

agnostic-api_deving

RepoGitHubGitLab
User-FilesystemGitHubGitLab
ai-bomGitHubGitLab
api-baseGitHubGitLab
apibrewGitHubGitLab
apifsGitHubGitLab
apifusefsGitHubGitLab
bibhelperGitHubGitLab
browser-fs-accessGitHubGitLab
chromium-automationGitHubGitLab
cross-platform-system-interactionGitHubGitLab
darwinkitGitHubGitLab
fswatch-Filesystem-Events-Watchfolder-Shell-ScriptGitHubGitLab
ipfs-api-mountGitHubGitLab
jail-shGitHubGitLab
lifoGitHubGitLab
mist.shGitHubGitLab
mkinitcpio-dirGitHubGitLab
portalGitHubGitLab
puppeteerGitHubGitLab
rm-safelyGitHubGitLab
sizesGitHubGitLab
swap.shGitHubGitLab
tombGitHubGitLab
unified-ai-apiGitHubGitLab
uutils-coreutilsGitHubGitLab
zenfs-archivesGitHubGitLab
zenfs-bundleGitHubGitLab
zenfs-coreGitHubGitLab
zenfs-linuxGitHubGitLab

ai-agents_deving

RepoGitHubGitLab
OmoiOSGitHubGitLab
PhoneixAIGitHubGitLab
accessibility-agentsGitHubGitLab
clahubGitHubGitLab
clawmetryGitHubGitLab
netclawGitHubGitLab
nexa-gaugeGitHubGitLab
niko-claude-skillsGitHubGitLab
notificareGitHubGitLab
pylibsmetaGitHubGitLab

cachyos_deving

RepoGitHubGitLab
CachyOS-PKGBUILDSGitHubGitLab
CachyOS-SettingsGitHubGitLab
New-Cli-InstallerGitHubGitLab
ananicy-rulesGitHubGitLab
cachy-chrootGitHubGitLab
cachy-updateGitHubGitLab
cachyos-repo-add-scriptGitHubGitLab
chwdGitHubGitLab
copr-linux-cachyosGitHubGitLab
kernel-managerGitHubGitLab
repo-manage-utilGitHubGitLab
scx-managerGitHubGitLab

git-management_deving

RepoGitHubGitLab
gha-repo-managerGitHubGitLab
git-release-shellGitHubGitLab
git-repo-managerGitHubGitLab
git-repo-worktrees-managerGitHubGitLab
github-api-scriptsGitHubGitLab
github-api-scripts1GitHubGitLab
github-codeownersGitHubGitLab
gitlab-enhancedGitHubGitLab
repo-descriptionGitHubGitLab

immutable-filesystem_deving

RepoGitHubGitLab
immutable-linux-frameworkGitHubGitLab

incus_deving

RepoGitHubGitLab
Image-ServerGitHubGitLab
Incus-MacOS-ToolkitGitHubGitLab
K8s-in-incusGitHubGitLab
LXD-ManagerGitHubGitLab
blincusGitHubGitLab
cluster-api-provider-incusGitHubGitLab
ctdeGitHubGitLab
distrobuilderGitHubGitLab
dotdropGitHubGitLab
ezpodman-sandboxGitHubGitLab
gh-actions-managerGitHubGitLab
incusGitHubGitLab
incus-agent-sysvinitGitHubGitLab
incus-app-containerGitHubGitLab
incus-cloud-initGitHubGitLab
incus-composeGitHubGitLab
incus-demo-serverGitHubGitLab
incus-deployGitHubGitLab
incus-dockerGitHubGitLab
incus-ghaGitHubGitLab
incus-goadGitHubGitLab
incus-image-serverGitHubGitLab
incus-imagesGitHubGitLab
incus-init-scriptsGitHubGitLab
incus-launch-vm-actionGitHubGitLab
incus-linux-toolkitGitHubGitLab
incus-osGitHubGitLab
incus-package-repoGitHubGitLab
incus-sdkGitHubGitLab
incus-ui-canonicalGitHubGitLab
incus-waydroid-toolkitGitHubGitLab
incus-windowsGitHubGitLab
incus-windows-toolkitGitHubGitLab
incus_container_gui_setupGitHubGitLab
incus_container_managerGitHubGitLab
incuslabGitHubGitLab
infra-dashboardGitHubGitLab
kapsuleGitHubGitLab
kapsule-incus-managerGitHubGitLab
lxd_incus_gui_appsGitHubGitLab
packer-plugin-incusGitHubGitLab
packer-plugin-incuschrootGitHubGitLab
podclawGitHubGitLab
polarGitHubGitLab
setup-incusGitHubGitLab
talosGitHubGitLab
talos-incusGitHubGitLab
terraform-incus-oci-image-updatingGitHubGitLab
waydroid-toolkitGitHubGitLab

linux-kernel_filesystem_deving

RepoGitHubGitLab
btrfs-dwarfs-frameworkGitHubGitLab
kernel-patchesGitHubGitLab
linux-cachyosGitHubGitLab
linux-distro-prefixGitHubGitLab
linux-distro-stage3GitHubGitLab
linux-over-the-airGitHubGitLab
linux-pivotGitHubGitLab
linux-powerwashGitHubGitLab
liquorix-unified-kernelGitHubGitLab
liqxanmodGitHubGitLab
lkfGitHubGitLab
lkmGitHubGitLab
ukmGitHubGitLab
xanmod-unified-kernelGitHubGitLab

neon-deving

RepoGitHubGitLab
KPortGitHubGitLab
docker-imagesGitHubGitLab
kde-builderGitHubGitLab
pkg-kde-dev-scriptsGitHubGitLab
pkg-kde-jenkinsGitHubGitLab
pkg-kde-toolsGitHubGitLab
qt-kde-team.pages.debian.netGitHubGitLab
ubuntu-coreGitHubGitLab

ops

RepoGitHubGitLab
Smart-File-OrganizerGitHubGitLab
achievementsGitHubGitLab
agentic-shellGitHubGitLab
bash-api-serverGitHubGitLab
bash-itGitHubGitLab
bashlyGitHubGitLab
build-serverGitHubGitLab
flatpak-repoGitHubGitLab
fork-sync-allGitHubGitLab
git-sizerGitHubGitLab
github-exporterGitHubGitLab
headroomGitHubGitLab
hrsyncGitHubGitLab
ipinfoGitHubGitLab
linux-shell-script-archiveGitHubGitLab
lowlighter-metricsGitHubGitLab
mass_cloneGitHubGitLab
namefixGitHubGitLab
operation-phantom-shellGitHubGitLab
org-mirrorGitHubGitLab
remote-syncGitHubGitLab
rtkGitHubGitLab
shell2httpGitHubGitLab
shellqueueGitHubGitLab
simple-deployGitHubGitLab
smartcdGitHubGitLab
unified-agnostic-apiGitHubGitLab
utility_shellGitHubGitLab
victoriametrics-metricsGitHubGitLab
webhookGitHubGitLab

penguins-eggs_deving

RepoGitHubGitLab
eggs-aiGitHubGitLab
eggs-guiGitHubGitLab
oa-toolsGitHubGitLab
penguins-distrobuilderGitHubGitLab
penguins-eggsGitHubGitLab
penguins-eggs-auditGitHubGitLab
penguins-eggs-bookGitHubGitLab
penguins-eggs-integrationsGitHubGitLab
penguins-eggs-prefixGitHubGitLab
penguins-eggs-stage3GitHubGitLab
penguins-immutable-frameworkGitHubGitLab
penguins-incus-platformGitHubGitLab
penguins-kernel-managerGitHubGitLab
penguins-over-the-airGitHubGitLab
penguins-pivotGitHubGitLab
penguins-powerwashGitHubGitLab
penguins-recoveryGitHubGitLab

rust-systems_deving

RepoGitHubGitLab
coreutilsGitHubGitLab
mdBookGitHubGitLab

taubyte_deving

RepoGitHubGitLab
taubyteGitHubGitLab

yaml-tooling_deving

RepoGitHubGitLab
CI-DebuggerGitHubGitLab
actions-orchestratorGitHubGitLab
activitysmith-github-actionGitHubGitLab
agentshieldGitHubGitLab
blueprintGitHubGitLab
confmgrGitHubGitLab
deardirGitHubGitLab
denoflowGitHubGitLab
directory-modelGitHubGitLab
dirstructxGitHubGitLab
fluent-github-actionsGitHubGitLab
gaviGitHubGitLab
git-queueGitHubGitLab
github-actions-virtualization-supportGitHubGitLab
github-actions-workflow-tsGitHubGitLab
graphizeGitHubGitLab
katachiGitHubGitLab
llm-docs-generatorGitHubGitLab
matrix-lockGitHubGitLab
mnemonicGitHubGitLab
models-generatorGitHubGitLab
pkgbuild-actionGitHubGitLab
project-memory-mcpGitHubGitLab
pyvertGitHubGitLab
scriptfsGitHubGitLab
super-yamlGitHubGitLab
system-cleanup-managerGitHubGitLab
veliteGitHubGitLab
xml-yaml-json-converterGitHubGitLab
y2jGitHubGitLab
yaml-fuseGitHubGitLab
yaml-sortGitHubGitLab
yamlerGitHubGitLab
yamllint-tsGitHubGitLab

Auto-generated by generate-dep-graph.sh. Do not edit manually. Last generated: 2026-06-12 (stub — full graph generated on next scheduled run)

This graph maps every OSP-bound repo in Interested-Deving-1896 to its upstream origin(s), as declared in each repo's ## Origins README section.

RepoOriginHostFork in I-D-1896
github-codeownerskohofinancial/github-codeownersGitHub
github-codeownersjjmschofield/github-codeownersGitHub
gitlab-enhancedopenos-project/git-management_deving/gitlab-enhancedGitLab

Summary

  • OSP-bound repos scanned: stub (full scan runs weekly via generate-dep-graph.yml)
  • Tooling dependencies tracked: github-codeowners (CODEOWNERS auditing across all OSP repos)

Tooling Dependencies

ToolPurposeUpstream
github-codeownersAudits CODEOWNERS coverage — surfaces ownership stats per repokohofinancial/github-codeowners

Source Tree

Auto-generated 2026-07-03 by scripts/generate-book-pages.py

Complete directory and file index of the fork-sync-all source hierarchy. Click any path to view it on GitHub.


/ (root)/

FileDescription
.clang-format
.dockerignore
.editorconfig
.gitignore
.gitlab-ci.yml
.gitmodules
.npmignore
.npmrc
.yamllint.yml
AGENTS.mdAI agent conventions, patterns, and known pitfalls
CHANGELOG.md
CONTRIBUTING.md
LICENSE
README.mdProject overview, mirror chain diagram, workflow count
book.tomlmdBook configuration — theme, search, output settings
registered-imports.jsonUpstream repos to keep in sync (registry)

--help/

DOCS/

generated/

FileDescription
glossary.md
source-tree.md

.devcontainer/

Dev container configuration (devcontainer.json, features)

features/

dotdrop/

git-filter-repo/

git-platform-clis/

gitr/

glab/

incus/

sync-in-server/

.dotdrop/

dotfiles/

templates/

generic/
go-service/
nextjs-app/
rust-service/
vite-app/

.github/

GitHub Actions workflows, issue templates, dependabot config

ISSUE_TEMPLATE/

workflows/

All 112 CI/CD workflow YAML files

FileDescription
a11y-pr-gate.yml
add-mirror-repo.yml
audit-arch-repos.yml
auto-merge-prs.yml
bdfs-dev-btrfs.yml
bdfs-dev-dwarfs.yml
bdfs-dev-overlay.yml
bdfs-dev.yml
bdfs-package.yml
book-export.yml
bootstrap-org.yml
bootstrap-triggers.yml
branch-hygiene-report.yml
btrfs-devel-sync.yml
bugzilla-failure-report.yml
bugzilla-milestone-ship.yml
build-arm64.yml
build-selfhosted.yml
build-x86.yml
build.yml
cancel-post-rotation.yml
cancel-stale-runs.yml
check-accessibility.yml
check-ci.yml
check-gitlab-sync.yml
check-ooc-ci.yml
check-shell-tools-ci.yml
checks.yml
ci.yaml
cleanup-branches.yml
cleanup-pollution.yml
clear-notifications.yml
clone-org.yml
codeql-analysis.yml
create-ooc-subgroups.yml
create-readmes.yml
critical-deploy-all.yml
critical-deploy-github-ooc.yml
critical-deploy-github-osp.yml
critical-deploy-gitlab.yml
critical-deploy-stub.yml
critical-deploy.yml
delete-stale-repos.yml
deploy-book.yml
devcontainer-sdk.yml
docker-to-incus.yml
dwarfs-pack-caller.yml
eco-audit.yml
enforce-agnostic-vendor.yml
flush-active-watchdog.yml
flush-lifecycle.yml
fork-neon-repos.yml
fsa-api.yml
full-audit.yml
full-chain-flush.yml
gen-arch-config.yml
generate-book-pages.yml
generate-dep-graph.yml
generate-notebooklm.yml
generate-repo-descriptions.yml
generate-sbom.yml
git-platform-sync.yml
gitbook-oss.yml
gl-storage-scan.yml
hw-detect-ci.yml
import-repo.yml
inject-badges.yml
inject-motto.yml
integrate-shell-tools.yml
labeler.yml
list-active-runs.yml
list-chromium-repos.yml
lts-readmes.yml
manage-repo-settings.yml
manage-subtrees.yml
merge-ready-prs.yml
merge-to-monorepo.yml
mirror-artifacts.yml
mirror-chain-dispatch.yml
mirror-flatpak.yml
mirror-ghcr.yml
mirror-orgs-full.yml
mirror-orgs-watchdog.yml
mirror-osp-to-gitlab.yml
mirror-osp-to-ooc.yaml
mirror-osp-to-ooc.yml
mirror-pypi.yml
mirror-releases.yml
mirror-rpm.yml
mirror-to-osp.yml
mirror.yaml
notify-manager.yml
notify-poller.yml
onboard-bugzilla.yml
onboard-repo.yml
opencode.yml
org-storage-maintenance.yml
ota-discover.yml
ota-opt-in.yml
ota-reconcile.yml
ota-release.yml
ota-self-update.yml
pin-manager.yml
pin-workflows.yml
pipeline-telemetry.yml
post-flush-prep.yml
pr-automation.yml
pr-gate.yml
pr-lifecycle-guard.yml
pre-flush-prep.yml
pre-mirror-ci-gate.yml
provision-maintenance.yml
push-kernel-content.yml
queue-manager.yml
quota-monitor.yml
quota-reserve.yml
rate-limit-rerun.yml
rate-limit-status.yml
readme-wizard.yml
rebase-lts.yml
rebase-prs.yml
reconcile-identity-assets.yml
reconcile-org-refs.yml
refresh-notebooklm-auth.yml
release.yaml
repo-manifest.yml
resolve-ci.yml
resolve-failures.yml
rotate-token.yml
runner-status.yml
seed-patchset-branches.yml
setup-dashboard-vars.yml
setup-gitlab-schedules.yml
setup-osp-mirrors.yml
shallow-reclone-chromium.yml
sync-agent-prices.yml
sync-btrfs-devel-branches.yml
sync-eggs-docs-to-book.yml
sync-forks.yml
sync-from-gitlab.yml
sync-fsa-forks.yml
sync-in.yml
sync-kde-groups-mirrors.yml
sync-kde-neon-mirrors.yml
sync-ona-projects.yml
sync-pieroproietti-forks.yml
sync-pieroproietti-gl-forks.yml
sync-registered-imports.yml
sync-registry-backend.yml
sync-registry-sources.yml
sync-shell-tools.yml
sync-template.yml
sync-to-bugzilla.yml
sync-to-gitlab-variant.yml
sync-to-gitlab.yml
sync-uaa-vendor.yml
sync-upstream-mirrors.yml
sync-upstream-sources.yml
test-time-format.yml
token-health.yml
track-agent-costs.yml
translate-docs.yml
translate-readmes.yml
trigger-artifact-mirror.yml
trigger-readme-update.yml
update-book-index.yml
update-infra-deps.yml
update-kde-builder-vendor.yml
update-quota-costs.yml
update-readmes.yml
update-workflow-triggers-doc.yml
upload-asset.yml
upload-notebooklm.yml
upstream-commits.yml
upstream-contribute-caller.yml
upstream-prs.yml
upstream-workflow-proposal.yml
validate-config.yml
validate-readme-render.yml
verify-fork-integrity.yml
verify-mirror-integrity.yml
vouch-check-pr.yml
vouch-manage.yml
vouch-onboard.yml
vouch-sync-codeowners.yml

.gitlab/

FileDescription
scheduled-maintenance.yml

merge_request_templates/

FileDescription
Default.md

.ona/

Ona automation config (automations.yaml)

FileDescription
automations.yaml

skills/

.ota/

FileDescription
schema.yml

.reuse/

FileDescription
dep5

DOCS/

mdBook source — all documentation pages

generated/

Auto-generated pages (rebuilt by generate-book-pages.py)

LICENSES/

FileDescription
GPL-3.0-only.txt

assets/

Static assets: brand logos, docs scaffolds, OTA stubs

brand/

Logo variants from discussion #125 (7 PNG options)

FileDescription
README.mdProject overview, mirror chain diagram, workflow count

ooc/

FileDescription
README.mdProject overview, mirror chain diagram, workflow count
cover-title.md

osp/

FileDescription
README.mdProject overview, mirror chain diagram, workflow count
cover-title.md

source/

FileDescription
README.mdProject overview, mirror chain diagram, workflow count
cover-title.md
logo-option-1.png

docs-scaffold/

Markdown scaffold files propagated to consumer repos

FileDescription
README.mdProject overview, mirror chain diagram, workflow count
SUMMARY.md
contributing.md
getting-started.md

ota-stub/

FileDescription
config.yml

config/

Single source of truth config files for all automation

data/

FileDescription
agent-cost-log.json

dep-graph/

Dependency graph outputs (origins.md, generated data)

FileDescription
origins.md
provenance.yml

docs/

Supplementary docs: workflow-triggers, NotebookLM outputs

notebooklm/

NotebookLM export placeholders (audio, video, slides, etc.)

FileDescription
README.mdProject overview, mirror chain diagram, workflow count

audio-overview/

FileDescription
README.mdProject overview, mirror chain diagram, workflow count
long/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
2026-06-17/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
medium/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
2026-06-17/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
short/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
2026-06-17/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count

flashcards/

FileDescription
README.mdProject overview, mirror chain diagram, workflow count
fewer/
easy/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
2026-06-17/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
hard/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
2026-06-17/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
medium/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
2026-06-17/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
more/
easy/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
2026-06-17/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
hard/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
2026-06-17/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
medium/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
2026-06-17/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
standard/
easy/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
2026-06-17/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
hard/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
2026-06-17/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
medium/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
2026-06-17/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count

infographic/

FileDescription
README.mdProject overview, mirror chain diagram, workflow count
landscape/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
2026-06-17/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
portrait/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
2026-06-17/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
square/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
2026-06-17/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count

quiz/

FileDescription
README.mdProject overview, mirror chain diagram, workflow count
fewer/
easy/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
2026-06-17/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
hard/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
2026-06-17/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
medium/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
2026-06-17/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
more/
easy/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
2026-06-17/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
hard/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
2026-06-17/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
medium/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
2026-06-17/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
standard/
easy/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
2026-06-17/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
hard/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
2026-06-17/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
medium/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
2026-06-17/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count

reports/

FileDescription
README.mdProject overview, mirror chain diagram, workflow count
blog-post/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
2026-06-17/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
briefing-doc/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
2026-06-17/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
study-guide/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
2026-06-17/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count

slide-deck/

FileDescription
README.mdProject overview, mirror chain diagram, workflow count
detailed/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
2026-06-17/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
presenter/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
2026-06-17/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count

video-overview/

FileDescription
README.mdProject overview, mirror chain diagram, workflow count
brief/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
2026-06-17/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
explainer/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count
2026-06-17/
FileDescription
README.mdProject overview, mirror chain diagram, workflow count

open-notebook/

FileDescription
README.mdProject overview, mirror chain diagram, workflow count

audio-overview/

FileDescription
README.mdProject overview, mirror chain diagram, workflow count

reports/

FileDescription
README.mdProject overview, mirror chain diagram, workflow count

open-notebooklm/

FileDescription
README.mdProject overview, mirror chain diagram, workflow count

audio-overview/

FileDescription
README.mdProject overview, mirror chain diagram, workflow count

openbooklm/

FileDescription
README.mdProject overview, mirror chain diagram, workflow count

audio-overview/

FileDescription
README.mdProject overview, mirror chain diagram, workflow count

reports/

FileDescription
README.mdProject overview, mirror chain diagram, workflow count

fsa-api/

FileDescription
README.mdProject overview, mirror chain diagram, workflow count

cli/

FileDescription
fsa.sh

config/

core/

adapters/

bdfs/
FileDescription
export.sh
import.sh
status.sh
chain/
FileDescription
flush.sh
status.sh
codebase/
FileDescription
drift.sh
log.sh
status.sh
sync.sh
deployments/
docs/
notifications/
FileDescription
list.sh
triage.sh
quota/
FileDescription
status.sh
repos/
FileDescription
list.sh
onboard.sh
security/
FileDescription
scan.sh
toggles/
FileDescription
list.sh
set.sh
workflows/
FileDescription
list.sh
run.sh
status.sh

lib/

FileDescription
fsa-adapter.sh

scripts/

FileDescription
scaffold-consumer.sh

server/

FileDescription
fsa-start.sh

uaa/

FileDescription
.gitignore
README.mdProject overview, mirror chain diagram, workflow count

.github/

workflows/
FileDescription
ci.yml
server-test.yml

scripts/

All first-party automation scripts

FileDescription
add-mirror-repo.sh
apply-brand.py
audit-arch-repos.sh
auto-merge-prs.sh
bdfs-dev-btrfs.sh
bdfs-dev-dwarfs.sh
bdfs-dev-overlay.sh
bdfs-dev.sh
bootstrap-org.sh
branch-name-conv.sh
check-accessibility.sh
check-ci.sh
check-ooc-ci.sh
check-osp-ci-summary.sh
check-osp-ci.sh
check-rate-limits.sh
check-readme-render.sh
check-vendor-agnostic.sh
check-workflow-yaml.py
cleanup-branches.sh
cleanup-pollution.sh
clone-org.sh
create-arch-repos.py
create-readmes.sh
critical-deploy-github.sh
critical-deploy-gitlab.sh
critical-deploy-stub.sh
critical-deploy.sh
devcontainer-base-image.py
devcontainer-build.sh
devcontainer-publish-features.sh
devcontainer-validate.py
dispatch-and-wait.sh
docker-to-incus.sh
dwarfs-pack.sh
file-bugzilla-report.sh
flush-sentinel.sh
generate-book-pages.pyGenerates DOCS/generated/ pages from config sources
generate-dep-graph.sh
generate-gitlab-stubs.py
generate-notebooklm.sh
generate-repo-descriptions.sh
generate-workflow-triggers-doc.py
gh-graphql.sh
git-platform-sync.sh
gitlab-storage-report.py
hw-build-env.sh
hw-detect.sh
import-repo.sh
init-kde-groups-mirror.py
inject-badges.sh
inject-motto.sh
kde-path-to-gl-id.json
list-active-runs.sh
list-chromium-gl-repos.py
list-ci-targets.py
local-quota-watch.sh
manage-repo-settings.sh
manage-subtrees.sh
merge-ready-prs.sh
merge-to-monorepo.sh
mirror-artifacts.sh
mirror-flatpak.sh
mirror-ghcr.sh
mirror-orgs.sh
mirror-osp-to-gitlab.sh
mirror-pypi.sh
mirror-releases.sh
mirror-rpm.sh
mirror-to-osp.sh
notebooklm-backend-open-notebook.sh
notebooklm-backend-open-notebooklm.sh
notebooklm-backend-openbooklm.sh
notebooklm-list-backends.sh
notebooklm-register-backend.sh
notebooklm-resolve-backend.sh
notifications.sh
notify-summary.py
notify-triage-ids.py
ona-mcp-server.pyFSA MCP server: 5 tools, SSE on port 8788
ona-projects.shOna project operator: sync, list, get-env
onboard-detect.py
onboard-repo.sh
org-storage-maintenance.sh
ota-deliver.sh
ota-discover.sh
ota-payload-build.sh
ota-reconcile.sh
patch-origins-sections.sh
pin-issues.sh
pin-profile.sh
pin-version.sh
pipeline-telemetry.sh
post-flush-prep.sh
pr-automation.sh
pre-flush-prep.sh
pre-mirror-ci-gate.sh
provision-maintenance.sh
push-kernel-content.sh
queue-manager.sh
quota-monitor.sh
quota-reserve.sh
readme-wizard.sh
rebase-lts.sh
rebase-prs.sh
reconcile-identity-assets.sh
reconcile-org-refs.sh
refresh-notebooklm-auth.sh
repo-manifest.sh
rerun-after-rate-limit.sh
resolve-ci.sh
resolve-failures.sh
rl-manifest-to-md.py
rotate-token.sh
run-all-tiers.sh
run-everything.sh
run-tier1-arm64.sh
run-tier2.sh
run-tier3.sh
runner-status.sh
scan-rate-limit-failures.sh
seed-patchset-branches.sh
setup-osp-mirrors.sh
shallow-reclone-gl.sh
sync-agent-prices.py
sync-all-forks.sh
sync-btrfs-devel-branches.sh
sync-eggs-docs-to-book.sh
sync-forks.sh
sync-from-gitlab.sh
sync-fsa-forks.sh
sync-in-client.sh
sync-in-server.sh
sync-kde-groups-mirrors.sh
sync-kde-neon-mirrors.sh
sync-pieroproietti-forks.sh
sync-pieroproietti-gl-forks.sh
sync-registered-imports.sh
sync-registry-sources.sh
sync-template.shTemplate propagation: CREATE/INJECT/PROPAGATE modes
sync-to-bugzilla.sh
sync-to-gitlab.sh
sync-upstream-mirrors.sh
sync-upstream-sources.sh
token-monitor.sh
translate-docs.sh
translate-readmes.sh
trigger-readme-update.sh
update-infra-deps.sh
update-readmes.sh
upload-asset.sh
upload-notebooklm.sh
upstream-commits.sh
upstream-prs.sh
upstream-workflow-proposal.sh
validate-cost-profiles.py
validate-gitlab-subgroups.py
validate-priority-tiers.py
validate-registered-imports.py
validate-template-config.py
validate-workflow-guards.pyValidates all 112 workflow files (5 checks)
validate-workflows.sh
variant-merge.py
verify-fork-integrity.sh
verify-mirror-integrity.sh
vouch-check-pr.sh
vouch-onboard.sh
vouch-registry.sh
vouch-seed.sh
write-summary.sh

eco/

includes/

Shared shell + Python includes sourced by multiple scripts

FileDescription
budget.shQuota budget helpers: budget_init, budget_check
bugzilla-api.sh
fsa-mode.shManaged/autonomous mode detection (3-tier check)
fsa-node-identity.shChain position layer: source/mirror/downstream-fork
gh-api.shGitHub API helpers: gh_get, gh_api, merge_upstream
llm.sh
pipeline-guard.sh
platform-adapter.sh
pr-lifecycle.sh
quota-instrument.sh
quota-snapshot.sh
shell-tools.sh
time_format.pyDual-format world-timezone display (484 IANA zones)

kport/

tests/

services/

sync-in/

FileDescription
install.sh
start.sh

tests/

eco/

ocs/

integration/

unit/

vendor/

Third-party components hosted/deployed by fork-sync-all

book-engine/

Agnostic book export backend (mdBook, MkDocs, Docusaurus, Pandoc)

FileDescription
README.mdProject overview, mirror chain diagram, workflow count

adapters/

Per-engine build adapters

config/

FileDescription
engines.yml

scripts/

FileDescription
export.sh
summary_to_nav.py

themes/

Brand themes (FSA theme: CSS, JS, cover)

fsa/

infra-dashboard/

Unified infrastructure platform (statuspage, dashboards)

FileDescription
.gitlab-ci.yml
README.mdProject overview, mirror chain diagram, workflow count
config.example.env
docker-compose.yml

.github/

workflows/
FileDescription
deploy-pages.yml

bin-pastebin/

.cargo/
FileDescription
config.toml
.github/
files/
workflows/
contrib/
cli/
FileDescription
client
resources/
syntaxes/
FileDescription
syntaxes.bin
themes/
FileDescription
ayu_dark.tmTheme
src/
FileDescription
main.rs
models/
routes/
static/
FileDescription
site.webmanifest
css/
FileDescription
index.css
pretty.css
fonts/
FileDescription
iosevka.css
ttf/
woff2/
js/
FileDescription
index.js
pretty.js
media/
templates/
tools/
FileDescription
prepush

builder-dashboard/

FileDescription
.gitignore
.prettierrc.json
.whitesource
[CachyOS Builder Dashboard.code-workspace](https://github.com/Interested-Deving-1896/fork-sync-all/blob/main/vendor/infra-dashboard/builder-dashboard/CachyOS Builder Dashboard.code-workspace)
README.mdProject overview, mirror chain diagram, workflow count
bun.lock
components.json
eslint.config.mjs
next.config.ts
package.json
postcss.config.mjs
tsconfig.json
.github/
workflows/
FileDescription
deploy.yml
public/
src/
app/
actions/
api/
logs/
[march]/
[pkgbase]/
FileDescription
route.ts
dashboard/
FileDescription
layout.tsx
audit-logs/
FileDescription
page.tsx
custom/
FileDescription
_tabs.tsx
layout.tsx
page.tsx
maintainers/
FileDescription
page.tsx
[username]/
FileDescription
page.tsx
packages/
FileDescription
page.tsx
repos/
FileDescription
page.tsx
[id]/
FileDescription
page.tsx
submissions/
[id]/
logs/
[march]/
[pkgbase]/
FileDescription
page.tsx
package-list/
FileDescription
page.tsx
profile/
FileDescription
page.tsx
[username]/
FileDescription
page.tsx
rebuild-queue/
FileDescription
page.tsx
repo-actions/
FileDescription
page.tsx
statistics/
FileDescription
page.tsx
validate/
FileDescription
page.tsx
components/
custom/
ui/
hooks/
lib/
api/
hooks/
FileDescription
use-infinite-list.ts

mirrorlist/

FileDescription
cachyos-mirrorlist

mirrorlist-proxy/

FileDescription
.air.toml
.gitignore
Dockerfile
LICENSE
README.mdProject overview, mirror chain diagram, workflow count
docker-compose.yml
go.mod
main.go

public-dashboard/

.github/
workflows/
FileDescription
checks.yml
public/
scripts/
FileDescription
prefill-cache.ts
src/
FileDescription
routeTree.gen.ts
router.tsx
assets/
FileDescription
icon.svg
components/
ui/
hooks/
lib/
server/
routes/
api/
styles/
FileDescription
globals.css

rate-mirrors/

FileDescription
.gitignore
.ignore
CHANGELOG.md
Cargo.lock
Cargo.toml
LICENSE
Makefile
README.mdProject overview, mirror chain diagram, workflow count
rustfmt.toml
stdin.txt
.github/
workflows/
FileDescription
release.yml
src/
target_configs/
targets/

statuspage/

FileDescription
.gitattributes
.upptimerc.yml
LICENSE
README.mdProject overview, mirror chain diagram, workflow count
.github/
ISSUE_TEMPLATE/
workflows/
api/
austria-mirror/
bangladesh-mirror/
canada-mirror/
canada-mirror-quebec/
cdn-77-cdn-worldwide/
china-mirror-nanjing/
china-mirror-ustc/
discuss/
finland-mirror/
france-mirror/
germany-mirror/
italy-mirror-m1k-cloud/
italy-mirror-next-works/
netherlands-mirror/
norway-mirror/
russia-mirror-archlinux-gay/
russia-mirror-cachy-arch-ru/
russia-mirror-jura12/
russia-mirror-metrosg-ru/
sweden-mirror/
switzerland-mirror/
usa-cdn-michigan/
usa-mirror/
usa-mirror-michigan/
usa-mirror-minnesota/
website/
wiki/
assets/
FileDescription
upptime-icon.svg
graphs/
austria-mirror/
bangladesh-mirror/
canada-mirror/
canada-mirror-quebec/
cdn-77-cdn-worldwide/
china-mirror-nanjing/
china-mirror-ustc/
discuss/
finland-mirror/
france-mirror/
germany-mirror/
italy-mirror-m1k-cloud/
italy-mirror-next-works/
netherlands-mirror/
norway-mirror/
russia-mirror-archlinux-gay/
russia-mirror-cachy-arch-ru/
russia-mirror-jura12/
russia-mirror-metrosg-ru/
sweden-mirror/
switzerland-mirror/
usa-cdn-michigan/
usa-mirror/
usa-mirror-michigan/
usa-mirror-minnesota/
website/
wiki/
history/
FileDescription
LICENSE

notifications-ui/

FileDescription
index.html

shell-tools/

Vendored shell utility repos (22 tools)

FileDescription
README.mdProject overview, mirror chain diagram, workflow count

Smart-File-Organizer/

FileDescription
.keep

User-Filesystem/

FileDescription
.keep

achievements/

FileDescription
.keep

bibhelper/

FileDescription
.keep

fswatch-Filesystem-Events-Watchfolder-Shell-Script/

FileDescription
.keep

git-release-shell/

FileDescription
.keep

hrsync/

FileDescription
.keep

ipinfo/

FileDescription
.keep

jail-sh/

FileDescription
.keep

linux-shell-script-archive/

FileDescription
.keep

mass_clone/

FileDescription
.keep

mist.sh/

FileDescription
.keep

mkinitcpio-dir/

FileDescription
.keep

namefix/

FileDescription
.keep

operation-phantom-shell/

FileDescription
.keep

remote-sync/

FileDescription
.keep

rm-safely/

FileDescription
.keep

shellqueue/

FileDescription
.keep

simple-deploy/

FileDescription
.keep

sizes/

FileDescription
.keep

smartcd/

FileDescription
.keep

swap.sh/

FileDescription
.keep

tomb/

FileDescription
.keep

utility_shell/

FileDescription
.keep

unified-agnostic-api/

Shell-based HTTP API framework with platform adapters

FileDescription
.gitignore
README.mdProject overview, mirror chain diagram, workflow count

.github/

workflows/
FileDescription
ci.yml
server-test.yml

Glossary

Auto-generated 2026-07-03 by scripts/generate-book-pages.py

Definitions for every term, acronym, and concept used across fork-sync-all.


Index

A: ACTOR_TZ · AGENTS.md · autonomous mode
B: book-engine · brand.yml · budget.sh
C: chain position · consumer repo · critical-deploy
D: DRY_RUN
E: Etc/GMT+N
F: FSA API · fsa-mode.sh · fsa-node-identity.sh · full-chain-flush
G: generate-book-pages.py · gh-api.sh · GitLab subgroup · GraphQL · GROUP_SORT_KEYS
I: IANA timezone · infra-core profile
M: managed mode · MCP server · mdBook · MIN_QUOTA · mirror chain
N: node identity
O: OOC · OSP · OSP-bound repo · OTA
P: platform-adapter.sh · pre-flush-prep · priority tiers
Q: queue-manager · quota-reserve · quota-snapshot.sh
R: registered-imports.json
S: SUMMARY.md · SYNC_TOKEN
T: template-manifest.yml · time_format.py
V: vendor/
W: workflow-quota-costs.yml · WORLD_ZONES


ACTOR_TZ
IANA timezone of the person who triggered a workflow. Set via `ACTOR_TZ`, `TRIGGERER_TZ`, or `GITHUB_ACTOR_TZ` env vars. Highlighted in world_table() output.
AGENTS.md
Convention file for AI agents working in this repo. Defines logging rules, YAML-safe shell patterns, quota management, workflow patterns, and known pitfalls.
autonomous mode
Operating mode when fork-sync-all is not present alongside a consumer repo. Bundled workflows activate and self-manage, scoped to the repo's own owner.
book-engine
Agnostic documentation export backend in `vendor/book-engine/`. Supports mdBook, MkDocs, Docusaurus, GitBook CLI, and Pandoc from a single Markdown source.
brand.yml
Single source of truth for fork-sync-all branding: logo URL, color palette, substitution tokens (`{{FSA_NAME}}` etc.), and book theme settings.
budget.sh
Shared include providing `budget_init`, `budget_check`, `budget_report`, `osp_priority_repos`, and `workflow_min_quota`. Reads per-workflow `min_quota` from `workflow-quota-costs.yml`.
chain position
Where a fork-sync-all instance sits in the mirror chain: `source` (Interested-Deving-1896), `mirror` (OSP/OOC), or `downstream-fork` (independent fork).
consumer repo
Any repo that receives template files from fork-sync-all via `sync-template.sh`. Defined in `config/template-consumers.yml`.
critical-deploy
Fast-lane workflow for emergency deployments: commit + push → aggressive queue clear → priority dispatch. Manual trigger only.
DRY_RUN
Environment variable flag. When `true`, scripts print what they would do without making any changes. Supported by all major scripts.
Etc/GMT+N
IANA timezone notation where the sign is inverted from UTC offset convention. `Etc/GMT+5` = UTC-5 (EST). All 484 IANA zones are included in `time_format.py`.
FSA API
The `ona-mcp-server.py` MCP server exposing 5 tools: `list_projects`, `get_project`, `create_environment`, `sync_projects`, `get_config_summary`. Runs on port 8788.
fsa-mode.sh
Three-tier managed/autonomous detection: (B) `FSA_MANAGED` repo variable → (A) GET `/repos/{owner}/fork-sync-all` → (C) token owner's fork-sync-all existence.
fsa-node-identity.sh
Extends fsa-mode.sh with chain position detection. Exports `FSA_NODE_POSITION`, `FSA_NODE_OWNER`, `FSA_UPSTREAM_OWNER`, `FSA_CHAIN_DEPTH`.
full-chain-flush
End-to-end pipeline: pre-flush-prep → mirror chain → post-flush-prep. Triggered manually or by critical-deploy.
generate-book-pages.py
Script that generates `DOCS/generated/` pages from live config sources. Also injects index + glossary into workflow-triggers.md.
gh-api.sh
Shared include providing `gh_api`, `gh_get`, `gh_api_graphql`, `merge_upstream`, `get_default_sha`. All status messages use `>&2`.
GitLab subgroup
Organizational unit in the `openos-project` GitLab group. Defined in `config/gitlab-subgroups.yml`. 14 subgroups covering ~225 repos.
GraphQL
Preferred over paginated REST for any loop fetching the same data for multiple repos. Counts as 1 REST call regardless of how many repos are queried.
GROUP_SORT_KEYS
Dict in `generate-workflow-triggers-doc.py` mapping group names to filename-substring lists for non-alphabetical display ordering.
IANA timezone
Standard timezone identifier from the IANA Time Zone Database (e.g. `America/Toronto`, `Europe/Paris`). `time_format.py` covers all 484 zones.
infra-core profile
Template profile providing CI hygiene + autonomous-fallback workflows. Includes PR automation, token rotation, branch cleanup, mdBook workflows, OTA, accessibility.
managed mode
Default operating mode when fork-sync-all is present. Bundled autonomous-fallback workflows detect this and skip themselves.
MCP server
Model Context Protocol server. `ona-mcp-server.py` exposes FSA operations as MCP tools consumable by any MCP-compatible AI agent.
mdBook
Rust-based static site generator used as the primary book engine. Source in `DOCS/`, config in `book.toml`, deployed to GitHub Pages by `deploy-book.yml`.
MIN_QUOTA
Minimum remaining REST quota required before a workflow proceeds. Set per-workflow in `config/workflow-quota-costs.yml`. Typically 500–1500.
mirror chain
Three-org pipeline: Interested-Deving-1896 → OpenOS-Project-OSP (GitHub) → openos-project (GitLab). Managed by mirror-to-osp.yml, mirror-osp-to-gitlab.yml.
node identity
The position of a fork-sync-all instance in the mirror chain. See `fsa-node-identity.sh`. Determines which operations the instance runs.
OOC
OpenOS-Project-Ecosystem-OOC — the third org in the mirror chain (GitHub). Receives mirrors from OSP.
OSP
OpenOS-Project-OSP — the second org in the mirror chain (GitHub). Receives mirrors from Interested-Deving-1896.
OSP-bound repo
A repo in Interested-Deving-1896 that is mirrored into OSP and managed by fork-sync-all (README updates, badge injection, CI checks, etc.).
OTA
Over-the-air update system. Delivers workflow and config updates from fork-sync-all to consumer repos without requiring manual PRs.
platform-adapter.sh
Uniform interface for GitHub, GitLab, Gitea, Forgejo, and Codeberg. Abstracts API differences behind a common shell interface.
pre-flush-prep
Pre-flight workflow run before full-chain-flush. Checks quota, validates configs, merges pending PRs, cleans stale branches.
priority tiers
Four-tier workflow priority system: Tier 1 CRITICAL (never cancelled), Tier 2 HIGH (mirror/sync), Tier 3 MEDIUM (READMEs/CI), Tier 4 LOW (translation/maintenance).
queue-manager
Workflow that deduplicates queued runs (keeps newest per workflow) and evicts runs queued > 25 min. Runs every 30 min.
quota-reserve
Workflow that cancels low-priority queued runs when quota drops below 1000. Uses per-workflow `min_quota` for cost-aware cancellation.
quota-snapshot.sh
Shared include that captures a REST quota snapshot and writes it to a GitHub Actions variable. Must run after `actions/checkout`.
registered-imports.json
Registry of upstream repos to keep in sync. Read by `sync-registered-imports.sh` and `sync-registry-sources.yml`.
SUMMARY.md
mdBook navigation file. Defines the book's table of contents. All book-engine adapters translate this into their native nav format.
SYNC_TOKEN
GitHub token used for cross-org operations. Shares the same 5000 req/hr REST bucket as `GH_TOKEN` (same user ID 202036334).
template-manifest.yml
Defines 6 named propagation profiles (full, mirror, infra-core, upstream-sync, standalone, shell-tools) and their file inclusion lists.
time_format.py
Shared Python module providing dual 12h/24h format across all 484 IANA timezones. Includes actor/runner timezone detection and `--test` self-test.
vendor/
Third-party components hosted/deployed by fork-sync-all. Not first-party scripts. Contains infra-dashboard, shell-tools, unified-agnostic-api, book-engine.
workflow-quota-costs.yml
Per-workflow REST call cost registry. Drives quota-reserve.sh cancellation, budget.sh pre-flight, and DOCS/quota-costs.md documentation.
WORLD_ZONES
Dynamic list of all 484 IANA timezone zones in `time_format.py`. Built at import time from `zoneinfo.available_timezones()`, sorted west→east.

Eco Audit

Generated 2026-06-29 by scripts/eco/eco-audit.sh Aligned with KDE Eco / Blue Angel DE-UZ 215 criteria.

Score: 🟡 14/20 (70%) — B — Good

CheckScoreDetail
❌ green hosting0/2Green hosting (❌ Not verified green — hosted by unknown)
✅ foss license2/2FOSS license present (LICENSE) + REUSE/SPDX compliant (.reuse/dep5 + LICENSES/)
✅ no telemetry2/2No telemetry/tracking found
⚠️ no forced updates1/2Possible forced update patterns (7 hits — review manually)
✅ concurrency groups2/2Concurrency groups: 164/181 workflows (90%)
✅ graphql adoption2/2GraphQL adopted in 35 scripts (reduces API quota consumption)
✅ dep minimalism2/2Low dependency footprint: 0.2 installs/workflow avg
⚠️ carbon estimate1/2Carbon estimate available: ~27.13 kg CO2e/year (stub — KEcoLab needed for precision)
❌ keco lab0/2KEcoLab: not yet configured (stub — requires GitLab CI + physical hardware)
✅ old hardware2/2No minimum hardware requirements specified (shell scripts run on any hardware)

Carbon Footprint Estimate

ParameterValueSource
Daily workflow runs~100Estimate
Avg job duration~3 minEstimate
Runner TDP~30WGitHub ubuntu-latest (2-core shared VM)
Azure PUE1.18Microsoft 2023 Sustainability Report
Grid intensity420 gCO2/kWhEPA eGRID 2022, MROW (Azure North Central US)
Annual estimate~27.13 kg CO2e/yearProxy — not measured

⚠️ This is a proxy estimate. Precise measurement requires KEcoLab.


Green Hosting

  • URL checked: https://interested-deving-1896.github.io/fork-sync-all/
  • Result: ❌ Not verified green — hosted by unknown
  • Checker: Green Web Foundation

KEcoLab (GitLab Stub)

KEcoLab is KDE's remote energy measurement lab. It uses a physical power meter connected to test hardware to measure actual watt-hours consumed per use case.

This cannot run on GitHub Actions — it requires physical hardware at KDE's infrastructure. The stub below is ready to activate when hosted on GitLab.

Setup steps

  1. Write KdeEcoTest scripts simulating user interactions with your software
  2. Add .gitlab-ci-eco.yml to your repo (template: scripts/eco/gitlab-ci-eco.yml.tpl)
  3. Submit to KEcoLab: https://invent.kde.org/teams/eco/remote-eco-lab
  4. Receive energy consumption report (watt-hours per use case)
  5. Apply for Blue Angel DE-UZ 215 if criteria are met

Resources


CI Efficiency Stats

MetricValue
Total workflows181
Workflows with concurrency groups164 (90%)
Scripts using GraphQL35
apt-get install calls20
pip install calls18
npm/yarn/bun install calls6

Blue Angel DE-UZ 215 Checklist

CriterionStatusNotes
FOSS licenseOpen source — transparency by design
No telemetry / trackingNo analytics, beacons, or tracking scripts
No forced updatesAll updates are opt-in via OTA system
Runs on old hardwareShell scripts — no minimum spec
User data controlNo user data collected
Energy measurement⏳ StubRequires KEcoLab (GitLab)
Documented energy use⏳ StubPending KEcoLab measurement
Green hosting❌ Not verified green — hosted by unknownGitHub Pages via Azure

Full glossary: Glossary · Eco resources: eco.kde.org

Pre-Flush Checklist

Steps to verify before triggering flush-lifecycle.yml (the recommended entry point) or full-chain-flush.yml directly (bypass mode only). Most are zero-API-call operations — safe to run while quota is exhausted.


1. Check quota

curl -sf -H "Authorization: token $SYNC_TOKEN" \
  "https://api.github.com/rate_limit" | python3 -c "
import sys, json
from datetime import datetime, timezone
d = json.load(sys.stdin)
core = d['resources']['core']
reset = datetime.fromtimestamp(core['reset'], tz=timezone.utc)
now = datetime.now(tz=timezone.utc)
eta = max(0, int((reset - now).total_seconds()))
print(f'Remaining : {core[\"remaining\"]}/{core[\"limit\"]}')
print(f'Reset at  : {reset.strftime(\"%H:%M:%S UTC\")}')
print(f'ETA       : {eta//60}m {eta%60}s')
"

pre-flush-prep requires at least 500 remaining to proceed past its quota pre-flight. Below that it exits 1 and emits a log line that rate-limit-rerun.yml detects — it will re-dispatch automatically after the reset. The flush itself needs ~1000–1500 to complete without hitting the reserve floor mid-way.


2. Run config validators

All must pass with zero errors.

python3 scripts/validate-gitlab-subgroups.py   config/gitlab-subgroups.yml
python3 scripts/validate-registered-imports.py registered-imports.json
python3 scripts/validate-registered-imports.py registered-imports.json --vouch-check
python3 scripts/validate-cost-profiles.py      config/workflow-cost-profiles.yml
python3 scripts/validate-priority-tiers.py     config/workflow-priority-tiers.yml
python3 scripts/validate-template-config.py
python3 scripts/validate-workflow-guards.py

Expected output pattern:

config/gitlab-subgroups.yml: 14 subgroups, N repos — ✅ Valid
validate-registered-imports: 157 entry/entries valid (157 unique targets, 157 unique sources)
vouch-check: 0 unvouched upstream org(s)
validate-cost-profiles: 42 profile(s) valid
validate-priority-tiers: N entries valid (tier1=19, tier2=19, tier3=62, tier4=54)
validate-template-config: 7 profile(s) valid, 80 consumer(s) valid
validate-workflow-guards: all checks passed (N workflows, ...)

If --vouch-check reports unvouched orgs, add them to .github/VOUCHED-upstreams.td after reviewing the upstream for supply-chain risk, then re-run.


3. Run the test suite

python3 -m pytest tests/ -v --tb=short

All tests must pass. Current baseline: 340 tests. A lower count means a test file was accidentally deleted or a conftest broke collection.


4. ShellCheck modified scripts

git diff --name-only HEAD~5 -- 'scripts/*.sh' | xargs -r shellcheck --severity=warning

SC1091 (not following sourced files) is expected and acceptable across all scripts that source includes/budget.sh, includes/gh-api.sh, or includes/pr-lifecycle.sh.


5. Check for open PRs

Open PRs that are green and mergeable should be merged before the flush. pre-flush-prep Step 2 auto-merges eligible PRs (mergeable_state == "clean"), but GitHub only computes mergeability after CI runs — ensure CI has completed on all open PRs before triggering.

Dependency-update PRs (chore(deps): update workflow dependencies) are safe to merge without review.


6. Check vendor/ agnostic state

bash scripts/check-vendor-agnostic.sh vendor

Must exit 0. Violations mean a vendored component has deployment-identity values hardcoded — fix before flushing.


7. Verify working tree is clean

git status --short
git log --oneline -5

Uncommitted changes won't be picked up by the flush. Commit or stash everything.


8. PR lifecycle guard health

The PR lifecycle guard (pr-lifecycle-guard.yml) gates OTA Release, Upstream PRs, and Rebase PRs. Verify quota-reserve.yml has run recently and the reserve floor is healthy (>=1000 remaining after reserve). If quota is tight, the guard will defer those workflows automatically — no manual action needed.


9. Vouch system state

# Confirm VOUCHED.td is current
cat .github/VOUCHED.td

# Confirm no unvouched upstream orgs
python3 scripts/validate-registered-imports.py registered-imports.json --vouch-check

If new repos were added to registered-imports.json since the last flush, their upstream orgs may not yet be in VOUCHED-upstreams.td. Add them before flushing so the advisory check stays clean.


10. Trigger

Once all the above are green:

  1. Go to flush-lifecycle.yml
  2. Click Run workflow
  3. Leave all inputs at defaults for a standard flush

flush-lifecycle.yml sets FLUSH_ACTIVE=true, holds a sentinel runner slot, then dispatches pre-flush-prepfull-chain-flushpost-flush-prep in sequence with quota reservation active throughout.

Bypass mode (advanced): trigger pre-flush-prep.yml directly if you need control over its inputs (skip_merge_prs, skip_cleanup, quota_wait_min). pre-flush-prep dispatches full-chain-flush automatically at the end of Step 8. Do not trigger full-chain-flush directly unless bypassing both the lifecycle wrapper and prep intentionally.


Quick reference — pre-flush-prep steps

StepActionSkippable
Quota pre-flightExit 1 + emit rate-limit log if < 500 remainingNo
1Cancel stale/queued runs older than STALE_MINNo
2Merge green PRs on main (mergeable_state == clean)skip_merge_prs=true
3Validate all configs (gate — aborts on failure)No
4Clean up merged branch debris across the orgskip_cleanup=true
5Remove stray template files from consumer reposskip_cleanup=true
6Resolve CI failures across configured targetsskip_resolve_failures=true
7Quota gate — wait up to QUOTA_WAIT_MIN for headroomNo
8Dispatch full-chain-flushNo

What happens after the flush

post-flush-prep.yml fires automatically via workflow_run: Full Chain Flush. It runs four verification checks and posts a summary. If it reports failures, check the step summary for which repos failed and why before re-flushing.

Template propagation (vouch workflows, SBOM pipeline, PR lifecycle guard) is delivered to the 80 consumer repos during the flush via sync-template.sh. No manual action is needed — the flush handles it.

Runbooks

Operational procedures for common and emergency situations.


Quota exhaustion

Symptoms: workflows fail with 403, gh api calls return empty, validate-config skips with "quota too low".

Check current state:

curl -sf -H "Authorization: token $SYNC_TOKEN" \
  "https://api.github.com/rate_limit" | \
  python3 -c "
import sys, json
from datetime import datetime, timezone
d = json.load(sys.stdin)
core = d['resources']['core']
reset = datetime.fromtimestamp(core['reset'], tz=timezone.utc)
now = datetime.now(tz=timezone.utc)
eta = max(0, int((reset - now).total_seconds()))
print(f'Remaining : {core[\"remaining\"]}/{core[\"limit\"]}')
print(f'Reset at  : {reset.strftime(\"%H:%M:%S UTC\")}')
print(f'ETA       : {eta//60}m {eta%60}s')
"

Recovery:

  1. Wait for the reset (up to 1 hour). The reset time is shown above.
  2. While waiting, use the time productively — all local operations (config validation, ShellCheck, pytest, file edits) work without quota.
  3. After reset, trigger pre-flush-prep.yml to clear the queue and restart the mirror chain cleanly.

Prevention: quota-reserve.yml cancels low-priority runs at < 1000 remaining. If exhaustion is recurring, check config/workflow-quota-costs.yml for unexpectedly expensive workflows (the cost_high and min_quota fields) and consider raising MIN_QUOTA thresholds. config/workflow-cost-profiles.yml has the detailed per-call breakdown if you need to trace where calls are going.


Queue pile-up

Symptoms: many workflows stuck in "queued" state, runners appear busy but nothing is completing.

Check:

# Via GitHub CLI (requires quota)
gh run list --repo Interested-Deving-1896/fork-sync-all --status queued --limit 50

Recovery:

  1. Trigger queue-manager.yml manually — it deduplicates and evicts runs queued > 25 minutes.
  2. If the queue is severely backed up, trigger pre-flush-prep.yml with skip_merge_prs=true and skip_cleanup=true — Step 1 aggressively clears stale runs before dispatching the flush.
  3. As a last resort, trigger critical-deploy.yml — it performs an aggressive queue clear and dispatches with priority.

Token expiry

Symptoms: token-health.yml opens an issue labelled token-monitor, or workflows fail with 401.

Check expiry:

bash scripts/token-monitor.sh

Rotate a token:

  1. Generate a new PAT at https://github.com/settings/tokens
  2. Go to rotate-token.ymlRun workflow
  3. Select the secret name from the dropdown
  4. Paste the new token value
  5. Leave validate checked
  6. Update the expiry date in AGENTS.md token rotation table

For OSP org secrets (MIRROR_TOKEN, ORG_MIRROR_OSP_TO_OOC), see the Token Rotation section in AGENTS.md — these require a separate PAT with admin:org on OpenOS-Project-OSP.


Mirror chain broken

Symptoms: repos in OSP or OOC are behind I-D-1896 by more than one cycle, or GitLab mirrors show stale commits.

Diagnose:

# Check GitLab sync status (requires quota)
gh workflow run check-gitlab-sync.yml --repo Interested-Deving-1896/fork-sync-all

Recovery by leg:

Broken legFix
I-D-1896 → OSPTrigger mirror-to-osp.yml manually
OSP → OOCTrigger mirror-osp-to-ooc.yaml manually
OSP → GitLabTrigger mirror-osp-to-gitlab.yml manually
GitLab → I-D-1896Trigger sync-from-gitlab.yml manually

For a full chain reset, trigger flush-lifecycle.yml — it runs pre-flush-prep, full-chain-flush, and post-flush-prep in sequence with quota reservation and the FLUSH_ACTIVE mutex active throughout. Trigger full-chain-flush.yml directly only when intentionally bypassing the lifecycle wrapper (e.g. quota is already reserved and pre-flight was run manually).


Config validation failure

Symptoms: validate-config.yml fails on push, blocking the flush.

Run locally to see the error:

python3 scripts/validate-gitlab-subgroups.py config/gitlab-subgroups.yml
python3 scripts/validate-registered-imports.py registered-imports.json
python3 scripts/validate-cost-profiles.py config/workflow-cost-profiles.yml
python3 scripts/validate-priority-tiers.py config/workflow-priority-tiers.yml
python3 scripts/validate-template-config.py
python3 scripts/validate-workflow-guards.py

Common causes:

  • Duplicate repo name in gitlab-subgroups.yml
  • Duplicate source_url or target_name in registered-imports.json
  • Workflow added to .github/workflows/ but not registered in workflow-priority-tiers.yml or workflow-sync.yml
  • Duplicate name in workflow-priority-tiers.yml

Vendor component agnostic check failure

Symptoms: enforce-agnostic-vendor.yml fails on a PR touching vendor/.

Run locally:

bash scripts/check-vendor-agnostic.sh vendor

The output shows the exact file, line, and category of violation. Fix by:

  • Removing the hardcoded fallback value (set to empty string)
  • Moving the value to a CI variable / repo var
  • Adding # check-vendor-agnostic: ignore if the value is genuinely deployment-agnostic (rare — document why)

README render failure

Symptoms: validate-readme-render.yml fails on a PR.

Run locally:

bash scripts/check-readme-render.sh README.md
# Also run the self-test to verify the checker itself is working:
bash scripts/tests/test-check-readme-render-mobile.sh

Common causes: unclosed fences, leaked log lines, bare [text] links without URLs, raw angle brackets, broken tables, missing H1.


OTA delivery failure

Symptoms: ota-release.yml fails for one or more forks, or a fork's ota-self-update.yml fails.

For a single fork:

  1. Check the fork's ota-self-update.yml run logs for the specific error
  2. Common causes: fork has diverged significantly, pinned_sha is stale, or the fork's .ota/config.yml has an invalid field
  3. To reset: update pinned_sha in the fork's .ota/config.yml to the current upstream HEAD SHA, then re-trigger ota-self-update.yml

To skip a fork temporarily: Set disabled: true in its config/ota-registry.yml entry.

To re-deliver to all forks: Push a new semver tag to fork-sync-allota-release.yml triggers automatically.


Incident response checklist

For any production incident affecting the mirror chain:

  1. Check quota — if exhausted, wait for reset before doing anything else
  2. Check queue — trigger queue-manager.yml to clear pile-ups
  3. Identify the broken leg — use check-gitlab-sync.yml and manual inspection
  4. Fix the specific leg — trigger the relevant mirror workflow directly
  5. Validate config — run all validators locally before triggering a flush
  6. Run pre-flush-prep — let it clean up and restart the chain
  7. Monitor — watch the first few workflow runs after recovery for secondary failures

Accessibility

This page documents the accessibility system built into fork-sync-all and propagated to all infra-core and upstream-sync consumer repos.


What the system does

Every repo in the OSP stack is audited for accessibility on every push to main and weekly via check-accessibility.yml. The audit covers five layers:

LayerToolWhat it checks
CODEOWNERSgithub-codeownersOwnership coverage %, unowned files, CODEOWNERS validation
README scanBuilt-inMissing alt text, non-descriptive links, table headers, reading level, bare URLs
WCAG 2.1 AApa11y + axe-coreHTML accessibility violations in generated docs
Audio overviewespeak-ngREADME → MP3 audio for visually impaired users
Braille outputliblouisREADME → Grade 2 English Braille (.brl file)

Accessibility artifacts

Each repo that has run check-accessibility.yml will have these files committed to its default branch:

FileFormatAudience
README.audio.mp3MP3 audioScreen reader users, visually impaired developers
README.brlBraille Grade 2Braille display users
accessibility-report.jsonJSONCI systems, dashboards, automation

Running the audit

On push: automatically triggered when README.md or CODEOWNERS changes.

Weekly: runs every Monday at 04:17 UTC.

Manually:

# Via GitHub CLI
gh workflow run check-accessibility.yml

# With options
gh workflow run check-accessibility.yml \
  -f repo=my-repo \
  -f fail_on_error=true

Locally (requires espeak-ng, python3-louis, pa11y):

sudo apt-get install espeak-ng ffmpeg python3-louis liblouis-data
npm install -g pa11y github-codeowners

REPO_DIR=. OWNER=my-org REPO=my-repo \
  AUDIO_ENABLED=true BRAILLE_ENABLED=true WCAG_ENABLED=true \
  bash scripts/check-accessibility.sh

Installing the runner dependencies

The check-accessibility.yml workflow installs these automatically on the GitHub Actions runner. For local use:

# Ubuntu / Debian
sudo apt-get install espeak-ng ffmpeg python3-louis liblouis-data

# macOS (Homebrew)
brew install espeak liblouis ffmpeg
pip3 install louis

# Node tools
npm install -g pa11y github-codeowners

CODEOWNERS coverage

Ownership coverage is measured by github-codeowners audit. Thresholds:

CoverageStatus
≥ 80%✅ Pass
50–79%⚠️ Warning
< 50%❌ Error

To see unowned files:

cd <repo>
github-codeowners audit -u

To validate your CODEOWNERS file:

github-codeowners validate

README accessibility standards

The README scan checks for:

  • Missing alt text — every ![]() image must have descriptive alt text
  • Non-descriptive links — avoid [click here], [here], [link], [read more]
  • Table headers — every markdown table must have a |---|---| separator row
  • Bare URLs — wrap URLs in descriptive link text: [description](url)
  • Reading level — avg sentence length ≤ 20 words is accessible; > 30 is flagged
  • H1 heading — every README must start with a # Title

WCAG 2.1 AA compliance

HTML docs in DOCS/generated/ are scanned with pa11y against the WCAG 2.1 AA standard. Common issues:

IssueFix
Missing alt on <img>Add descriptive alt text
Low colour contrastEnsure 4.5:1 ratio for normal text, 3:1 for large text
Missing form labelsAssociate <label> with every <input>
Missing landmark regionsWrap content in <main>, <nav>, <header>
Empty linksAdd descriptive text inside <a> tags

Audio overview

README.audio.mp3 is generated by espeak-ng, a lightweight open source TTS engine. The README is stripped of markdown syntax before synthesis for cleaner output.

Playback:

# Any media player
mpv README.audio.mp3
vlc README.audio.mp3

# Command line
ffplay README.audio.mp3

Braille output

README.brl is generated by liblouis, the standard open source Braille translation library used by NVDA, JAWS, and VoiceOver. Output is Unified English Braille (UEB) Grade 2.

To display on a Braille terminal:

# Most Braille displays accept .brl files directly via their driver software
# On Linux with brltty:
brltty -f README.brl

Upstream tools tracked

All accessibility tools are forked into Interested-Deving-1896 and mirrored to the accessibility_deving GitLab subgroup:

ToolPurposeUpstream
nvdaScreen reader for Windowsnvaccess/nvda
osaraREAPER accessibility (audio production)jcsteh/osara
liblouisBraille translation libraryliblouis/liblouis
espeak-ngText-to-speech engineespeak-ng/espeak-ng
axe-coreWCAG rules enginedequelabs/axe-core
pa11yCLI WCAG auditingpa11y/pa11y
github-codeownersCODEOWNERS auditingkohofinancial/github-codeowners
target-size-highlighterWCAG 2.5.5 pointer target visualiseraccessibility-tools/target-size-highlighter
z-index-focus-overrideWCAG 2.4.11 focus indicator bookmarkletaccessibility-tools/z-index-focus-override
READMEAccessible HTML doc generator (no-JS)canalplus/README

Further reading

Contributing

Conventions for adding workflows, scripts, config entries, and vendor components.


Adding a workflow

  1. Create the workflow file in .github/workflows/

  2. Register in priority tiers — add an entry to config/workflow-priority-tiers.yml using the workflow's name: field (not the filename):

    - name: "My New Workflow"
      tier: 3   # MEDIUM — adjust based on criticality
    

    Tier guide: 1=CRITICAL (never cancelled), 2=HIGH (mirror chain), 3=MEDIUM (default), 4=LOW (cancelled first under quota pressure)

  3. Register in workflow-sync — add to config/workflow-sync.yml:

    • Under github_only if it has no GitLab CI counterpart (most workflows)
    • Under paired if it has a matching GitLab CI job
  4. Add a concurrency group if triggered by schedule or workflow_run:

    concurrency:
      group: my-workflow-name
      cancel-in-progress: true
    
  5. Add a quota pre-flight if the workflow makes API calls and runs frequently. Use the shared include — do not inline the curl block:

    - name: Checkout
      uses: actions/checkout@v4
    
    - name: Quota pre-flight
      id: quota
      env:
        GH_TOKEN: ${{ secrets.SYNC_TOKEN }}
        MIN_QUOTA: "500"   # adjust to your workflow's actual cost
      run: |
        source scripts/includes/quota-snapshot.sh
        quota_snapshot
    

    Checkout must come before the quota pre-flight step. quota-snapshot.sh is sourced from the checked-out repo — if checkout runs after, the runner cannot find the file and the step fails with No such file or directory.

    Gate subsequent steps with if: steps.quota.outputs.skip == 'false'.

    The include writes remaining, reset_time, and skip to GITHUB_OUTPUT and a status line to GITHUB_STEP_SUMMARY. It also supports an optional QUOTA_WRITE_VAR: "true" env var that writes a QUOTA_SNAPSHOT repo Actions variable — useful for chain entry/exit points so downstream workflows can read quota state without an API call via ${{ vars.QUOTA_SNAPSHOT }}. Currently enabled on pre-flush-prep, full-chain-flush, and post-flush-prep.

    Fork note: QUOTA_WRITE_VAR requires the token to have repo scope (classic PAT) or variables: write (fine-grained PAT). If the write fails the workflow continues — it logs a warning and the snapshot is simply not updated. The variables: write permission must also be declared at the workflow level:

    permissions:
      actions: write
      contents: read
      variables: write
    
    
    
  6. Validate:

    python3 scripts/validate-workflow-guards.py
    python3 scripts/validate-priority-tiers.py config/workflow-priority-tiers.yml
    
  7. Update the workflow triggers doc — if the workflow belongs to a group where display order matters (e.g. Full Pipeline, Mirror Chain), add its filename pattern to GROUP_SORT_KEYS in scripts/generate-workflow-triggers-doc.py, then regenerate:

    python3 scripts/generate-workflow-triggers-doc.py
    cp docs/workflow-triggers.md DOCS/workflow-triggers.md
    

    GROUP_SORT_KEYS maps group names to filename-substring lists in the desired display order. Workflows not listed sort alphabetically after the pinned ones. Groups without an entry sort fully alphabetically — only add an entry when alphabetical order is wrong for that group.


Adding a script

Scripts live in scripts/. All logging must go to stderr — never stdout — because many functions are called inside $(...) captures where stdout becomes the captured value.

info() { echo "[my-script] $*" >&2; }
warn() { echo "[warn] $*" >&2; }

If the script sources includes/budget.sh or includes/gh-api.sh, add the shellcheck directive:

# shellcheck source=includes/budget.sh
source "$(dirname "${BASH_SOURCE[0]}")/includes/budget.sh"

Run ShellCheck before committing:

shellcheck --severity=warning scripts/my-script.sh

Adding a config entry

New Ona project

Add to config/ona-projects.yml under projects::

  my-repo:
    repo: https://github.com/OpenOS-Project-OSP/my-repo
    name: "my-repo"
    project_id: ""   # populated by sync-ona-projects workflow on first run
    branch: main
    classes: [Regular]
    description: "Brief description of the project"
    tags: [osp-bound]

Then trigger sync-ona-projects.yml with dry_run=true to preview, or dry_run=false to create the project in Ona (requires ONA_TOKEN secret).

New repo to GitLab mirror chain

Add to config/gitlab-subgroups.yml under the appropriate subgroup:

  rust-systems_deving:
    repos:
      - my-new-repo

Then validate:

python3 scripts/validate-gitlab-subgroups.py config/gitlab-subgroups.yml

New repo to upstream sync

Add to registered-imports.json:

{
    "source_url": "https://github.com/upstream-org/repo-name",
    "target_name": "repo-name",
    "platform": "github",
    "added": "2026-06-07T00:00:00Z"
}

Then validate:

python3 scripts/validate-registered-imports.py registered-imports.json

New workflow priority tier entry

See "Adding a workflow" above — step 2.


Adding a vendor component

vendor/ is for third-party components that fork-sync-all hosts or deploys. It is not for first-party scripts or config.

Before adding:

  • Confirm the component is genuinely third-party (not a script you wrote)
  • Confirm it will be deployed or served by fork-sync-all (not just referenced)

When adding:

  1. Place under vendor/<component-name>/
  2. Strip all distro-specific or org-specific hardcoded defaults — see the agnostic rule below
  3. Add a README.md with a "Before the first deploy" section covering all required CI variables
  4. Run the agnostic check:
    bash scripts/check-vendor-agnostic.sh vendor/<component-name>
    

Agnostic rule

No deployment-identity values may appear as hardcoded fallback defaults in vendored components. This includes:

  • Public URLs: ${VITE_ENDPOINT_URL:-https://api.myorg.com}
  • Org/repo slugs: ${MIRRORLIST_REPO:-MyOrg/my-repo}
  • Arch/repo paths: ${MIRROR_REPO_PATHS:-x86_64/core}
  • Distro names: ${DISTRO:-cachyos}

Allowed:

  • Localhost dev URLs: ${API_URL:-http://localhost:5862}
  • Generic paths: ${MIRRORLIST_PATH:-mirrorlist/mirrorlist}
  • Single-word tokens: ${LOG_LEVEL:-info}
  • UI strings: ${APP_NAME:-Infra Dashboard}

To suppress a specific line that is intentionally non-agnostic:

SOME_VAR="${SOME_VAR:-value}"  # check-vendor-agnostic: ignore

enforce-agnostic-vendor.yml runs automatically on every push/PR touching vendor/.


Commit conventions

Follow the existing commit message style:

scope: short description

Longer explanation if needed. Focus on why, not what.

Common scopes: fix, feat, config, docs, vendor, scripts, ci.


Before opening a PR

# Config validators
python3 scripts/validate-gitlab-subgroups.py config/gitlab-subgroups.yml
python3 scripts/validate-registered-imports.py registered-imports.json
python3 scripts/validate-cost-profiles.py config/workflow-cost-profiles.yml
python3 scripts/validate-priority-tiers.py config/workflow-priority-tiers.yml
python3 scripts/validate-template-config.py
python3 scripts/validate-workflow-guards.py
# ^ also validates workflow-quota-costs.yml entry counts and consistency

# Test suites
python3 -m pytest tests/ -v --tb=short
bash scripts/tests/test-check-readme-render-mobile.sh

# ShellCheck (for any .sh files changed)
git diff --name-only HEAD -- 'scripts/*.sh' | xargs shellcheck --severity=warning

# Vendor check (if vendor/ was touched)
bash scripts/check-vendor-agnostic.sh vendor

# README render check
bash scripts/check-readme-render.sh README.md

All must pass before the PR is ready for merge.


Forking this repo

If you fork fork-sync-all into your own org, a few things need attention:

Required secrets

Copy all secrets from the secrets table in README.md. At minimum SYNC_TOKEN is required — most workflows will skip or fail without it.

Token scope for QUOTA_SNAPSHOT

Three workflows (pre-flush-prep, full-chain-flush, post-flush-prep) write a QUOTA_SNAPSHOT repo Actions variable after their quota pre-flight. This variable lets downstream chained workflows read quota state without an API call via ${{ vars.QUOTA_SNAPSHOT }}.

The write requires:

  • Classic PATrepo scope is sufficient (already needed by most workflows)
  • Fine-grained PAT — must include variables: write repository permission

If the write fails (wrong scope, token too restricted) the workflow logs a warning to stderr and continues — nothing breaks, QUOTA_SNAPSHOT just won't be updated for that run. Downstream workflows reading ${{ vars.QUOTA_SNAPSHOT }} will see the last successfully written value, or an empty string on first run.

To confirm the variable is being written, check the "Quota pre-flight" step log for QUOTA_SNAPSHOT variable updated (HTTP 204). If you see QUOTA_SNAPSHOT variable write failed (HTTP 403), your token needs the variables: write permission and the workflow needs:

permissions:
  variables: write

FSA mode detection

Forked instances are detected as downstream-fork by fsa-node-identity.sh and skip source-only operations (readmes, badges, fork-sync, templates, translate) to prevent duplicate work. See Architecture for the full node identity model.

Config files to update

FileWhat to change
config/gitlab-subgroups.ymlYour GitLab group and subgroup names
registered-imports.jsonYour upstream repos
config/template-consumers.ymlYour consumer repos
AGENTS.mdUpdate org names throughout