Module 4: The Sync Engine
Understand how L3 distributes managed files across all repos.
Estimated time: 15 minutes
What Gets Synced
The Distribution Engine ensures every registered repo has the same standardized set of workflows, skills, and configurations. Here's the full list of managed files:
Global Scope (distributed to every repo)
| File | Purpose |
|---|---|
claude-code.yml | Full Claude Code implementation workflow |
claude-code-plan.yml | Claude planning-only workflow |
assign-linear-project.yml | Linear project verification on issue creation |
standardize-issue.yml | Auto-standardize new issues via Claude |
l3-lifecycle skill | Lifecycle states, labels, GitFlow conventions |
linear-issue-routing skill | Rules for creating and routing Linear issues |
settings.json | Claude Code permissions and plugin config |
.claudeignore | Files Claude should ignore |
husky/pre-commit | Git pre-commit hook |
Optional Scope (only for repos that include them)
| File | Purpose | Used By |
|---|---|---|
fe-vite-project skill | Frontend project conventions | data-intel-fe, kv-internal-crm-fe, compass-fe |
process-meetings skill | Meeting processing conventions | Repos that handle meeting data |
How Scope Resolution Works
When the sync engine runs for a given repo, it resolves which files to distribute using this algorithm:
- If the repo has an explicit
files:key — use only those files (full override, bypasses scope logic) - Otherwise:
- Start with all
scope: globalfiles - Remove any keys in the repo's
exclude:list - Add any keys in the repo's
include:list (must bescope: optional)
- Start with all
- Cleanup: Any managed file already present in the target repo that is NOT in the resolved set gets deleted
For example, greylockit/data-intel-fe has include: ["fe-vite-project"], so it receives all 9 global files plus the frontend skill. A backend repo with no include gets only the 9 global files.
How Sync Runs
The sync engine is a shell script (.ops/sync.sh) that can be run:
.ops/sync.sh # sync all repos
.ops/sync.sh --repo org/name # sync a single repo
.ops/sync.sh --dry-run # show what would happenPer-Repo Process
For each registered repo (except l3-platform itself, which has sync: false):
- Resolve the file list using the scope algorithm
- Select the correct GitHub token (
GH_TOKEN_KVfor Khosla repos,GH_TOKEN_GENERALfor everything else) - Shallow-clone the target repo (
gh repo clone --depth 1) - Copy all resolved source files from
.ops/into the clone - Delete any managed files that aren't in the resolved set
- Generate
.github/linear-project.jsonfrom the repo's Linear config in sync.yml - Commit as
l3-platform[bot]with message:chore(ops): sync managed files from l3-platform - Push strategy:
- First attempt: direct push to
main - If rejected (branch protection): create a timestamped branch
ops-sync/YYYYMMDD-HHMMSS, push it, and open a PR - If a
devbranch exists, also push there directly
- First attempt: direct push to
- Apply branch protection rulesets via the GitHub API
- Set
delete_branch_on_merge=trueon the repo
Automatic Trigger
The ops-sync.yml workflow runs sync.sh automatically on any push to main that touches .ops/. It also supports manual runs via workflow_dispatch with dry-run and single-repo targeting options.
Branch Protection Rulesets
The sync engine applies two rulesets to every registered repo:
Ruleset 1: Branch Protection
- Protects
mainanddevbranches - Prevents deletion and force pushes
- Requires PRs (but 0 approving reviews required)
- Only repo admins can bypass
Ruleset 2: Branch Naming
Enforces a naming convention for all branches (except main, dev, develop, staging):
^(feature|bugfix|hotfix|spike)/[A-Za-z0-9]+-.*$
^release/[0-9]+\.[0-9]+\.[0-9]+.*$
^ops-sync/.*$This means branches must follow patterns like feature/PL-42-add-auth or bugfix/GL-58-fix-dates. The ops-sync/* pattern whitelists the sync engine's own branches.
First-Time Setup: install.sh
For new repos not yet receiving synced files, .ops/install.sh handles the bootstrap:
- Installs a core set of workflows, skills, and configs
- Generates
linear-project.jsonfrom the repo's Linear team config - Can run locally (
--repo org/name) or remotely viacurlfrom GitHub
For developer onboarding, install.sh --dev-setup ensures you have yq and gh installed and guides you through setting up the superpowers Claude Code plugin.