Explains how changes to the Flowfile monorepo are gated, versioned and released, including version sync, stub and docs drift checks, Alembic migrations and pinned dependencies.
Install the "flowfile-change-control" agent skill from https://github.com/Edwardvaneechoud/Flowfile/tree/main/.claude/skills/flowfile-change-control into .claude/skills/flowfile-change-control/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "flowfile-change-control", then confirm the skill loads.
Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
Type this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
skills CLI
$ npx skills add Edwardvaneechoud/Flowfile --skill flowfile-change-control -a codex
Project install goes to .agents/skills/; add -g for ~/.codex/skills/.
Install the "flowfile-change-control" agent skill from https://github.com/Edwardvaneechoud/Flowfile/tree/main/.claude/skills/flowfile-change-control into .agents/skills/flowfile-change-control/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "flowfile-change-control", then confirm the skill loads.
Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
skills CLI
$ npx skills add Edwardvaneechoud/Flowfile --skill flowfile-change-control -a cursor
Project install goes to .agents/skills/; add -g for ~/.cursor/skills/.
Install the "flowfile-change-control" agent skill from https://github.com/Edwardvaneechoud/Flowfile/tree/main/.claude/skills/flowfile-change-control into .cursor/skills/flowfile-change-control/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "flowfile-change-control", then confirm the skill loads.
Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
skills CLI
$ npx skills add Edwardvaneechoud/Flowfile --skill flowfile-change-control -a gemini-cli
Project install goes to .agents/skills/; add -g for ~/.gemini/skills/.
Install the "flowfile-change-control" agent skill from https://github.com/Edwardvaneechoud/Flowfile/tree/main/.claude/skills/flowfile-change-control into .gemini/skills/flowfile-change-control/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "flowfile-change-control", then confirm the skill loads.
Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
Installs for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
skills CLI
$ npx skills add Edwardvaneechoud/Flowfile --skill flowfile-change-control -a github-copilot
Project install goes to .agents/skills/; add -g for ~/.copilot/skills/.
Install the "flowfile-change-control" agent skill from https://github.com/Edwardvaneechoud/Flowfile/tree/main/.claude/skills/flowfile-change-control into .github/skills/flowfile-change-control/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "flowfile-change-control", then confirm the skill loads.
GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
skills CLI
$ npx skills add Edwardvaneechoud/Flowfile --skill flowfile-change-control -a opencode
OpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
Install the "flowfile-change-control" agent skill from https://github.com/Edwardvaneechoud/Flowfile/tree/main/.claude/skills/flowfile-change-control into .opencode/skills/flowfile-change-control/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "flowfile-change-control", then confirm the skill loads.
OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
Facts
Skill name
flowfile-change-control
GitHub stars
373
Token cost
~7.3k tokens
SKILL.md length
3,158 words
Files
1
Skills in repo
19
Repo updated
First seen
Licence
MIT
At a glance
Explains how changes to the Flowfile monorepo are gated, versioned and released, including version sync, stub and docs drift checks, Alembic migrations and pinned dependencies.
Works in 6 steps: How change is classified and gated here → Non-negotiables — with rationale and the… → Release mechanics → …
Bumping the Flowfile app version across all version manifests
SKILL.md covers When NOT to use this skill, 1. How change is classified…, 2. Non-negotiables — with… and 3. Release mechanics, plus 4 more sections
Calls git, make and gh; reaches events.flowfile.app; needs GH_TOKEN
What it does
This is the gatekeeper skill for the repository: it sorts a change into a lane and names the CI gate that fires for it. Touching any of the five version manifests triggers a version-sync job, changes to the flowfile_frame public API trigger a stubs check, and edits to the formula docs or the polars-expr-transformer pin trigger a formula-docs check. A change to the database models has no automated gate, so you must write the Alembic migration yourself, and the fastapi, polars and litellm dependencies are treated as deliberate pins.
It also documents CI quirks: a legacy CodeQL workflow that fails weekly because it points at a missing config, harmlessly, since GitHub's default code scanning setup is what reports results; and a main test workflow whose PR runs cancel superseded runs while main-branch runs never do. The description adds release tag mechanics for v-prefixed and wasm-v-prefixed tags, the real branch-protection state with ghost required checks and admin bypass, and a standing agreement on whether agents may run git commit or git stash.
It points to sibling skills for testing, build and environment setup, configuration flags, cross-package contracts, past-bug archaeology and documentation work. The shown part of its non-negotiables section begins with never force-pushing main.
When your agent uses it
Bumping the Flowfile app version across all version manifests
Adding an Alembic migration after changing the database models
Editing a pinned dependency such as fastapi, polars or litellm
Preparing or reviewing a release tag
Working out why a pull request will not go green
Example prompts
“I changed models.py in flowfile_core, so tell me what I need to add before this PR can merge.”
“Bump the Flowfile version and run the lockstep checks.”
“The check-stubs job is failing on my PR, so explain why and how to clear it.”
“Prepare the release tag for the next Flowfile version and list the gates it must pass.”
Requirements
A checkout of the Flowfile repository
GitHub CLI for inspecting workflows and branch protection
Workflow steps
6 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit d98b76d. It shows what the files ask for, not the result of running them.
Tool permissions
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Runs code
Shell commands in SKILL.md call:
git
make
gh
python3
poetry
cargo
python
curl
jq
docker
From the folder's file list and the shell code blocks in SKILL.md.
Network
Hosts in commands or code, which the agent is likely to contact:
events.flowfile.app
From URLs in SKILL.md, links to its own repository left out.
Credentials
Names these keys or tokens, usually read from environment variables:
GH_TOKEN
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Context cost
Flowfile Change Control loads about 7.3k tokens when it runs. Until then it costs about 188 tokens; SKILL.md has 3,158 words of instructions outside code blocks.
Always· name and description, kept in context so the agent knows when to use it
~188
When it runs· the whole SKILL.md, loaded when a task matches
~7.3k
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
Safety
Auto-check passed
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
Download SKILL.mdSave it as .claude/skills/flowfile-change-control/SKILL.md (or your agent's skills folder).
name
flowfile-change-control
description
How changes to the Flowfile monorepo are classified, gated, versioned, and released — version-lockstep bump/check machinery, the stub and formula-docs drift gates, Alembic migration discipline, deliberate dependency pins (fastapi, polars), the v*/wasm-v* release-tag mechanics, real branch-protection state (ghost required checks, admin bypass), and the standing no-commit/no-stash agent working agreement. Use when bumping the app version, adding an Alembic migration, touching flowfile_frame's public API or the formula docs generator, editing a pinned dependency (fastapi, polars, litellm), preparing or reviewing a release/tag, wondering why a PR won't go green, or deciding whether an agent may run `git commit`/`git stash`.
Flowfile change control
When NOT to use this skill
Writing or debugging tests → flowfile-testing-and-validation.
Local dev-server / build / Docker setup → flowfile-build-and-env.
Env vars and feature flags → flowfile-config-and-flags.
CI is the workflow set under .github/workflows/ (ls it for the current list). The legacy codeql.yaml fails every Monday because it references the missing .github/codeql/codeql-config.yml. This is harmless noise, not a blocker: GitHub Advanced Security default setup is separately configured and live (gh api repos/<org>/Flowfile/code-scanning/default-setup → "state":"configured", weekly, covers python/js-ts/actions/rust) and is what actually reports CodeQL results.
test.yaml (the primary CI gate, ~620 lines) is the only workflow with a concurrency group: PR runs cancel superseded runs of themselves, but main-branch runs are never cancelled — the file's own comment explains why: "docker-publish / release pipelines key off completed main builds."
2. Non-negotiables — with rationale and the incident behind each
2a. Never force-push main
CONTRIBUTING.md: "Don't force-push to main. Releases build from it." docker-publish.yml publishes kernel Docker images from main (kernel-path-filtered, only when the kernel version is unpublished; app images publish from v* tags); test.yaml runs full CI from main. Live branch protection additionally sets allow_force_pushes: false, and repo ruleset id 2660650 ("Only admin commits") adds non_fast_forward + required_linear_history blocks (verified live via gh api repos/.../branches/main/protection and gh api repos/.../rulesets). A force-push to main would desync in-flight release/Docker pipelines that key off a specific commit.
2b. Version bumps move in lockstep — never hand-edit a manifest
Five files carry the app version and must always agree:
pyproject.toml → [tool.poetry] version (line 3)
shared/_version.py → __version__
flowfile_frontend/src-tauri/Cargo.toml → [package] version
This exists because of a real production incident (commit b21f518c, PR #547, "Centralize version management across all manifests"): the version used to be read from 8 places with drifted hardcoded fallbacks (0.5.0 / 0.12.0 / 0.12.3 / "unknown"). In frozen PyInstaller sidecars, importlib.metadata.version("Flowfile") doesn't resolve, so a fallback could write a non-version string into the NOT NULLdb_info.app_version column — breaking desktop startup. The fix built the tooling below; use it, don't reinvent it.
bash
# Bump — rewrites all 5 files, nothing else
python tools/bump_version.py X.Y.Z
make bump-version VERSION=X.Y.Z # same, via Make
# Check — prints all 5, exits 1 on drift
python3 tools/check_version_sync.py
make check-version # same, via Make
# Release-gate form: also assert the canonical version equals a value
python3 tools/check_version_sync.py --expect X.Y.Z
Gotchas:
make bump-version also refreshes Cargo.lock (cargo update -p flowfile) when cargo is on PATH; calling tools/bump_version.py directly does not, so run that command yourself in that case.
kernel_runtime/pyproject.toml and flowfile_wasm/package.json (the flowfile-editor npm package) are deliberately NOT synced to the app version — they have their own release cadence (kernel image version, wasm-v* npm tags). Don't "fix" them to match.
The version-sync CI job runs unconditionally on every push/PR but is not in test-summary's needs list and is not a required branch-protection check — a version-sync failure fails that job but won't by itself block a merge the way you'd expect. Don't rely on it as your only signal; run make check-version yourself before opening a version-touching PR.
2c. Stub drift gate (make check_stubs) — fails CI silently for newcomers
flowfile_frame ships committed .pyi type stubs for its public surface (FlowFrame, Expr, every submodule, py.typed). If you add/change/remove a public method, class, or top-level symbol in flowfile_frame and don't regenerate stubs, check-stubs (CI job, gated on the backend_frame path filter) fails with no obvious link back to what you changed — it just reports a .pyi git diff.
bash
make stubs # regenerates all .pyi files, then prunes unused imports (ruff --select F401 --fix)
make check_stubs # stubs + `git diff --exit-code` on the .pyi files; CI runs exactly this
Three generators run in sequence: expr_stub_generator.py → expr.pyi, flow_frame_stub_generator.py → flow_frame.pyi, submodule_stub_generator.py → every other .pyi including __init__.pyi. Always run make stubs after any public API change and stage the diff (agents: hand off the commit per §6) — this is the single most common newcomer-trips-CI moment for anyone working in flowfile_frame. Full stub-authoring guidance lives in flowfile-frame-and-codegen; this skill only covers the gate.
2d. Formula-docs gate (make check_formula_docs) — same failure shape, different surface
docs/users/formulas/functions.md is auto-generated from polars-expr-transformer docstrings (header comment in the file itself says so — never hand-edit it). Bump the polars-expr-transformer pin, or otherwise change what generates that page, without regenerating it, and check-formula-docs (CI job, gated on a formula_docs path filter covering the generator script, the doc file, pyproject.toml, and the lockfile) fails on an unrelated-looking doc diff.
bash
make formula_docs # regenerate docs/users/formulas/functions.md
make check_formula_docs # formula_docs + `git diff --exit-code` on that file; CI runs exactly this
CONTRIBUTING.md doesn't mention this gate, so a contributor bumping polars-expr-transformer for an unrelated reason can hit a red documentation.yml build. If you see check-formula-docs fail, this is why; run make formula_docs and stage the regenerated page (agents: hand off the commit per §6).
2e. Alembic migrations: numeric prefix discipline
flowfile_core/flowfile_core/alembic/versions/ holds the numbered chain (001_initial_schema.py onward); ls the directory for the current head — never trust a count in prose.
Rules, with the incident behind each:
Add a new migration for any change to flowfile_core/flowfile_core/database/models.py; never hand-edit a migration that has already merged to main. Alembic itself was retrofitted in response to a real bug (commit 0ded1ebf, PR #403) after a run-type mismatch between local and Docker databases needed an undocumented downgrade path (006_normalize_run_type.py) — the whole migration system exists because "align local db and worker db" had to be attempted twice by hand before Alembic was added.
Approved exception — PR #738 only: the maintainer approved dialect-portability edits to revisions 002, 016, 020 and 026 so a fresh PostgreSQL catalog can traverse the existing chain. Limit edits to dialect-specific defaults/SQL and constraint handling; preserve SQLite schema and behavior, revision IDs and ordering. Schema redesign and data-semantic changes still require a new migration. Validate with test_sqlite_schema_unchanged using CATALOG_BASELINE_REF set to the pre-portability base, plus real PostgreSQL upgrade/downgrade coverage.
Numeric-prefix collisions bite long-running branches. Two branches cut from the same base each add, say, 029_*.py independently; whichever merges second collides or silently shadows revision ordering. This has already happened in-tree (b484a117 fix migrations on a long-lived branch was a direct fix for exactly this). Before adding a migration, check origin/main's current highest number, not your branch's — someone else may have already claimed NNN.
Importing flowfile_core has a side effect you need to know about: run_startup_migration() fires automatically at import time (flowfile_core/flowfile_core/database/init_db.py) unless FLOWFILE_SKIP_STARTUP_MIGRATION is set. This runs Alembic against whatever DB get_database_url() resolves to — including your live local catalog DB if you're not careful. Set FLOWFILE_SKIP_STARTUP_MIGRATION=1 for any diagnostic import of flowfile_core that isn't meant to touch the DB.
2f. Deliberate dependency pins — do not "fix" these without a mandate
Pin
Value
Why it's pinned
Evidence
fastapi / starlette
~0.142.2 / >=1.3.1 (root and kernel_runtime/pyproject.toml, kernel image 0.6.1)
Raised 2026-10-01 for the Starlette Dependabot alerts; the explicit starlette floor exists because FastAPI no longer caps it. FastAPI ≥0.132 422s a JSON body without Content-Type, so every JSON call into core/worker/kernel must send the header (incident 17 in flowfile-failure-archaeology).
The 2026-05 attempt (eff7287b, #457) was reverted without a recorded reason; the missing core→worker header is the likely cause.
cryptography
>=48.0.1,<49.0.0
49+ ships no x86_64 macOS wheels, which breaks the Intel desktop build (release.yamlmacos-15-intel) and Intel pip installs. The Dependabot alerts fixed only in 49/50 (X.509 verifier, PKCS#7 decryption) are in APIs Flowfile does not call.
cryptography 49.0.0 changelog.
polars
>=1.39.0, !=1.43.0, !=1.43.1, <1.44 (pyproject.toml; floor set by polars-grouper>=0.6.0 and polars-simed requiring polars>=1.39, guarded by tools/tests/test_polars_pin_floor.py; 1.43.0/.1 deadlock SQLContext.execute over scan_delta frames — catalog SQL readers/views hang)
Must move together with kernel_runtime's own Polars pin, flowfile_frame, and the version-coupled polars-* plugin packages (e.g. pl-fuzzy-frame-match). Kernel containers read their own poetry.lock at startup to surface/detect drift. Bumping the root pin alone breaks the kernel/frame contract.
Root CLAUDE.md "Things to Avoid"; CONTRIBUTING.md additionally still claims a Windows-only <=1.25.2 ceiling that was removed (single cross-platform pin now) — CONTRIBUTING is stale on this point, follow the pyproject.toml value, not the prose.
Intentional for 256-bit random tokens (no password-guessing surface to slow down with a KDF). The CodeQL "weak hash" alert on this line is a known false positive — do not "fix" it with bcrypt/argon2/PBKDF2.
Root CLAUDE.md; verified in-file (hashlib.sha256(...).hexdigest(), one-way, "never recoverable" per the module docstring).
If an agent (or CodeQL, or a linter) flags any of these pins, the correct action is to leave it alone and, if truly necessary, open a Discussion/issue to get the maintainer's sign-off first — not to "fix" it inline.
2g. Deliberate non-features — don't treat NotImplementedError as a TODO
The codebase has a set of intentional, by-design refusals — places where a feature is scoped out, not half-built. Examples: standalone Polars codegen refuses to emit code for external-source / cloud-storage / Kafka / catalog nodes ("Use FlowFrame export" instead — connector_handlers.py, code_generator.py); exported projects raise NotImplementedError for server-backed flowfile_ctx calls (global artifacts, catalog) with warnings surfaced in the export manifest; Kernel (Python Script) nodes are skipped by Export-to-Python; flowfile_frame refuses lambdas in expressions and join_asof/join_where; the bundled flowfile CLI web UI only accepts localhost:63578. If you find one of these while working a task, it is a documented product boundary, not a bug to close — check the surrounding code/docs for the refusal message before "completing" it. Full inventory of these boundaries belongs to flowfile-node-development / flowfile-frame-and-codegen; this skill flags the pattern so you don't file (or fix) a phantom bug.
3. Release mechanics
3a. The checklist
make bump-version VERSION=X.Y.Z
Only if cargo was missing during the bump: cd flowfile_frontend/src-tauri && cargo update -p flowfile
make check-version — must print "All versions in sync"
If this release adds a telemetry event or prop (shared/telemetry.pyEVENTS changed): redeploy tools/telemetry_collectorbefore tagging — the deployed collector silently drops unknown events, and curl -s https://events.flowfile.app/health | jq .schema must already list them
Open a PR (branch protection blocks direct pushes to main), get it merged
Tag the merge commit lowercasevX.Y.Z and push the tag
This fires pypi-release.yml, release.yaml, anddocker-publish.yml (app Docker images) simultaneously (§3b)
First release on the tag-triggered path: confirm docker-publish.yml actually fired on the tag (tag pushes ignore the paths: filter — documented GH behavior, but unexercised here). If it didn't, workflow_dispatch with publish_app: true publishes the app images at the manifest version — the intended escape hatch, safe because the new version's tags don't exist on Docker Hub yet.
Automatic, but confirm it: the release job generates latest.json with tools/make_latest_json.py and attaches it to the release (§3d) — check the asset landed (gh release view vX.Y.Z --json assets | grep latest.json)
3b. One v* tag push → three workflows
Workflow
What it does
Hard gate
pypi-release.yml
Builds web frontend into flowfile/flowfile/web/static/, poetry build, publishes to PyPI via Trusted Publishing (OIDC) — no API token
python3 tools/check_version_sync.py --expect "${GITHUB_REF#refs/tags/v}" — dies instantly if tag ≠ manifest version
release.yaml
Builds Tauri desktop installers on a 4-platform matrix (macOS arm64/x86_64, Windows, Linux), signs/notarizes macOS, publishes the GitHub Release
Same check_version_sync.py --expect gate, run per-platform before the Rust/PyInstaller build starts
docker-publish.yml
Publishes app Docker images (flowfile-core/-worker/-frontend) as :<version> + :latest (no latest for --suffixed prerelease tags); self-heals any unpublished kernel image version in the same run
Same check_version_sync.py --expect gate, plus tools/check_kernel_version_sync.py (kernel/images.py kernel pins must match kernel_runtime/pyproject.toml)
The shared gate means: tag before bumping = all release pipelines fail fast, which is the intended failure mode (better than shipping a mismatched artifact).
wasm-v* tags separately fire npm-publish-wasm.yml, which publishes flowfile-editor to npm via trusted publishing.
Show full SKILL.md (1,246 more words)Show less
3c. docker-publish.yml fires once per release, plus kernel-only runs from main
App images publish once per release, from the v* tag (the old release: published re-fire and per-main-push publishing were removed — the GH_TOKEN PAT on release.yaml's release step no longer serves that re-fire purpose). Kernel images (flowfile-kernel-base/ml/lite) publish from main pushes touching kernel paths, and only when flowfile-kernel-*:<kernel_version> is absent from Docker Hub (tools/docker_publish_matrix.py checks; workflow_dispatchforce_kernel overrides, publish_app republishes app images at the manifest version). Published version tags are therefore immutable in practice. Versions come from the manifests (root and kernel_runtime/pyproject.toml), with the --expect gate tying app tags to the git tag per §2b.
3d. The auto-updater manifest
tauri.conf.json's updater endpoint expects a latest.json asset on each GitHub Release. The release job now generates one: tools/make_latest_json.py --version "${GITHUB_REF_NAME#v}" --artifacts-dir artifacts --out latest.json, listed in the release files:. It maps the four platform keys onto the release assets (Flowfile_aarch64.app.tar.gz, Flowfile_x64.app.tar.gz, Flowfile_<version>_x64-setup.exe, Flowfile_<version>_amd64.deb) and pairs each with its .sig by an independent rglob — bundles and signatures are uploaded as separate artifacts, so they never sit in the same directory — failing the release when either is missing, ambiguous or empty. tools/tests/test_make_latest_json.py covers it.
Two things that are still true: the check 404s until the newest non-prerelease release carries a latest.json (the endpoint always resolves against /releases/latest, never against the installed version); and prerelease tags get a manifest too, which is inert because /releases/latest skips prereleases (use an -rc tag to validate manifest generation without offering the update to anyone).
3e. Tag hygiene — read before tagging
GitHub's v* trigger filter is case-sensitive. Capital-V tags (V0.10.1, V0.12.3 exist in this repo's history) fire nothing. Always tag lowercase vX.Y.Z.
A tag literally named main exists in this repo's tag namespace, which makes git <cmd> main print warning: refname 'main' is ambiguous and can resolve to the tag instead of the branch (tags win over branches in ref resolution). Always use origin/main or refs/heads/main for comparisons, never bare main.
A suffixed tag (e.g. v0.10.1-rc.1) is auto-flagged as a GitHub prerelease (contains(github.ref_name, '-') in release.yaml) so test builds never become the public "Latest" release — use a -suffix for any tag you don't want promoted.
4. Branch protection & required checks — the real, live state
Read this before telling anyone (human or agent) to "wait for CI to go green" or "wait for required checks":
bash
gh api repos/Edwardvaneechoud/Flowfile/branches/main/protection
As of 2026-07-03 this returns 8 required contexts: electron-tests-macos, electron-tests-windows, test-web, backend-tests-windows, backend-tests (macos-latest, 3.11), backend-tests (ubuntu-latest, 3.10/3.11/3.12).
electron-tests-macos and electron-tests-windows no longer exist — they were removed in the Electron→Tauri migration (commit 3777c661, #462). A required context that no workflow ever reports means branch protection can mathematically never be satisfied for a non-admin PR — the checks tab will show those two as perpetually pending, forever.
backend-tests (ubuntu-latest, 3.13), coverage, kernel-tests, check-stubs, check-formula-docs, docs-test, test-summary, version-sync, all E2E workflows, and the Claude review are not required checks — they can be red and a PR is still technically mergeable by protection rules (modulo the ghost-check problem above).
Reviews require required_approving_review_count: 1 and require_code_owner_reviews: true, but there is no CODEOWNERS file in the repo (verified: git ls-files | grep -i codeowners → empty) — the code-owner requirement is a no-op.
A separate repo ruleset, id 2660650 "Only admin commits" (active, targets refs/heads/main), duplicates the same stale required-checks list and layers on required_linear_history + deletion/non-fast-forward/creation blocks. Its bypass actors are OrganizationAdmin (always) and a repository-role id (always) — current_user_can_bypass: "always" for the maintainer.
Practical consequence: the maintainer merges PRs via admin/ruleset bypass, not by waiting for protection to auto-clear. The real aggregate CI signal to look at is the test-summary job in test.yaml (if: always(), fails if any non-skipped job in its needs list failed) — but note test-summary's needs list itself excludes version-sync, so a version-drift failure won't even show up there. If you're asked to verify a PR is "ready," check test-summary and version-sync separately — neither one alone is the full picture, and neither is a required GitHub check.
CONTRIBUTING.md's actual bar (not GitHub's mechanical one) is simpler and is what you should hold an agent-authored PR to:
One logical change per PR; smaller PRs review faster.
Commit messages: short imperative subject, "why" in the body if not obvious from the diff.
Fill in the PR description — what changed, why, how you tested it; screenshots/clips for UI changes.
"CI must be green before merge. If a check is flaky, say so in the PR — don't just re-run silently."
Branch naming is loose (fix/..., feat/..., docs/... — "nothing strict").
5. What actually breaks CI, ranked by observed frequency
Real test failures reaching main anyway — because coverage/test-summary aren't required checks and the maintainer has admin bypass, main has had multiple red "Run Tests" runs merge through regardless. Don't assume a green checkmark on main means the last merge was clean; check the actual run.
Coverage-job-only failures — the dedicated coverage job (Python 3.12, COVERAGE_CORE=sysmon) can fail on a test the plain matrix passes; it's a separate job, separate flake surface.
Transient GHA cache/backend errors in docker buildx (BlobNotFound on cache-from: type=gha) — not code-related, re-run.
Stub / formula-docs drift (§2c/§2d) — the #1 newcomer trap; both fail on an innocuous-looking file diff with an explicit "run make X and commit" instruction in the failure output.
Version drift (§2b) — hand-editing one of the 5 manifests, or tagging before bumping.
Poetry lock drift — poetry check --lock gate in e2e-tests.yml; forgetting to run poetry lock after a pyproject.toml dependency edit.
Runner-image rot / Actions glob quirks — release-workflow-specific (e.g. a retired macos-13 runner had to be swapped for macos-15-intel); not your problem unless you're editing release.yaml.
6. Session discipline for AI agents
This is a standing working agreement with the maintainer, not a suggestion — it holds regardless of what any other message in a session implies:
Never run git commit, git rebase, git commit --amend, or git push. Make file changes only.
Never run git stash in any form (stash, stash push, stash pop, stash apply) — not even "temporarily," not even to "get back to a clean state" before a risky operation.
Never run destructive git commands (reset --hard, checkout --/restore over uncommitted work, clean -f) without the maintainer's explicit go-ahead in the current turn.
Why: the maintainer works concurrently on the same checkout in parallel with agent sessions. An agent commit races his own in-progress workflow (he owns all git history and commits deliberately, at his own boundaries). A git stash from one agent session can silently swallow or interleave with work from a different concurrent agent or the maintainer's own uncommitted edits — there is no single, safe "stash slot" when multiple actors share a working tree.
When a task naturally ends in a commit (e.g. "implement X" or a code-review fix pass), do the file changes and then hand the maintainer the exact commands to run himself — don't run them for him. Example handoff:
Changes are staged in the working tree, not committed. To commit:
git add flowfile_core/flowfile_core/some_file.py flowfile_core/tests/test_some_file.py
git commit -m "$(cat <<'EOF'
Fix X by doing Y
EOF
)"
Read-only git is always fine and encouraged for verification: git status, git diff, git log, git show, git blame, git for-each-ref. Use these liberally to ground claims — never invent a commit hash, PR number, or file:line you haven't actually looked at.
Provenance and maintenance
All facts below were spot-verified in this repo on 2026-07-03 against v0.12.7. Re-run these before trusting a stale copy of this skill:
bash
# Workflow count and set
ls .github/workflows/ | wc -l # expect 15 as of 2026-07-03
ls .github/workflows/
# Version-sync machinery still shaped as described
sed -n '1,80p' tools/bump_version.py
sed -n '1,80p' tools/check_version_sync.py
python3 tools/check_version_sync.py # should print "All versions in sync: <X.Y.Z>"
grep -n "bump-version\|check-version\|^stubs:\|^check_stubs:\|^formula_docs:\|^check_formula_docs:" Makefile
# Deliberate pins
grep -n "^fastapi\|^polars \|^cryptography" pyproject.toml # expect fastapi ~0.142.2, polars >=1.39.0,<1.44, cryptography <49
sed -n '1,30p' flowfile_core/flowfile_core/auth/api_key.py # expect hashlib.sha256(...).hexdigest()
# Alembic migration count (root CLAUDE.md's number rots fast — trust this, not prose)
ls flowfile_core/flowfile_core/alembic/versions/ | sort
# FastAPI revert incident
git log --all --oneline --grep="Reverting upgrade Fastapi" # expect eff7287b on feature/LLM-security-patches
# CodeQL dual-state (legacy workflow broken, default setup live)
cat .github/workflows/codeql.yaml | grep config-file
git ls-files .github/codeql/ # expect empty (missing config)
gh api repos/Edwardvaneechoud/Flowfile/code-scanning/default-setup # expect "state":"configured"
# Branch protection reality (ghost required checks, no CODEOWNERS)
gh api repos/Edwardvaneechoud/Flowfile/branches/main/protection
git ls-files | grep -i codeowners # expect empty
gh api repos/Edwardvaneechoud/Flowfile/rulesets # expect ruleset id 2660650 "Only admin commits"
# Tag hygiene facts
git tag | grep -E "^V[0-9]" # expect capital-V tags exist (e.g. V0.12.3)
git tag | grep -viE "^v?[0-9]" # expect stray branch-named tags incl. "main"
# v*/wasm-v* release triggers
grep -n "check_version_sync" .github/workflows/pypi-release.yml .github/workflows/release.yaml
grep -n "on:" -A24 .github/workflows/docker-publish.yml # confirm push(main kernel paths + v* tags) + dispatch(publish_app/force_kernel)
# latest.json updater manifest (generated by the release job)
grep -n "make_latest_json" .github/workflows/release.yaml # expect the generate step + latest.json in files:
gh release view <newest tag> --repo Edwardvaneechoud/Flowfile --json assets | grep -i latest.json # expect a match on releases built since it landed
Facts that will rot fastest (re-check on every use of this skill, don't trust cached numbers): current app version (grep version pyproject.toml), migration count (ls the versions dir), workflow file count and names, and the exact required-check-context list from branches/main/protection — all four have already drifted once from what root CLAUDE.md claims.
Flowfile Change Control next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
Flowfile Change Control compared with similar skills
Skill
Stars
Used in
Tokens
Auto-check
Licence
Repo updated
Flowfile Change Control this skillEdwardvaneechoud/Flowfile
Safely plan and execute dependency maintenance for JavaScript/TypeScript (npm, pnpm) and GitHub Actions, including npm lockfiles, pnpm workspaces, catalogs, overrides, SHA-pinned action versions…
This skill should be used when a brepjs GitHub Actions job is red or behaving oddly on github.com (a remote CI run, not a local pre-commit/pre-push hook) — "CI failed", "ci-pass is failing", "npm ci…
Moves a package from another TryGhost repository into Ghost as an internal workspace package while keeping its Git history, with checkpoints for the steps that need an administrator.
Adds Worktrunk-specific rules to the tend CI workflows: Codecov polling, Rust test commands, labels and review criteria for pull requests handled in CI.
Maps the /ai/ subsystem of flowfile_core, its three agent tiers, litellm seam, BYOK keys and rate limits, and sets rules for extending or debugging it safely.
Maps Flowfile's core, worker, frontend, kernel, scheduler and shared services and the design contracts between them, for onboarding and cross-service debugging.
Recreates every Flowfile development and build environment from scratch, with exact version pins and an explanation of what each Makefile target really does.
Runbook for closing gaps between a Flowfile visual flow's results and its exported Polars or FlowFrame Python code, measured by tests rather than by eye.
Catalog of Flowfile's environment variables and runtime flags: what each does, where the code reads it, its default, and where the docs disagree with the code.
Turn a plain-English description ("a node that runs on the kernel and does XGBoost predictions", "a node that trims whitespace", "an ML clustering node") into a correct single-file Flowfile custom…
Explains how changes to the Flowfile monorepo are gated, versioned and released, including version sync, stub and docs drift checks, Alembic migrations and pinned dependencies. This is the gatekeeper skill for the repository: it sorts a change into a lane and names the CI gate that fires for it. Touching any of the five version manifests triggers a version-sync job, changes to the flowfile_frame public API trigger a stubs check, and edits to the formula docs or the polars-expr-transformer pin trigger a formula-docs check.
When should I use Flowfile Change Control?
Flowfile Change Control fits situations like: bumping the Flowfile app version across all version manifests; adding an Alembic migration after changing the database models; editing a pinned dependency such as fastapi, polars or litellm; preparing or reviewing a release tag.
How do I install Flowfile Change Control in Claude Code?
Run `npx skills add Edwardvaneechoud/Flowfile --skill flowfile-change-control -a claude-code`. Or copy the skill folder (.claude/skills/flowfile-change-control in Edwardvaneechoud/Flowfile) into .claude/skills/flowfile-change-control in your project. Claude Code loads it when a task matches its description.
How do I install Flowfile Change Control in Codex?
Run `npx skills add Edwardvaneechoud/Flowfile --skill flowfile-change-control -a codex`. Or copy the skill folder (.claude/skills/flowfile-change-control in Edwardvaneechoud/Flowfile) into .agents/skills/flowfile-change-control in your project. Codex loads it when a task matches its description.
Can I use Flowfile Change Control in Cursor, Gemini CLI or GitHub Copilot?
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add Edwardvaneechoud/Flowfile --skill flowfile-change-control -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/flowfile-change-control, .gemini/skills/flowfile-change-control, .github/skills/flowfile-change-control and .opencode/skills/flowfile-change-control in your project.
What does Flowfile Change Control need to run?
Going by SKILL.md and its folder, Flowfile Change Control needs the command-line tools its instructions call (git, make, gh, python3, poetry and cargo) and credentials named GH_TOKEN. Our summary lists: A checkout of the Flowfile repository; GitHub CLI for inspecting workflows and branch protection.
Does Flowfile Change Control access the network?
SKILL.md names 1 domain. In commands or code: events.flowfile.app; the agent is likely to contact it when it follows the instructions. This is read from the text; nothing was executed.
Is Flowfile Change Control safe to install?
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
What licence does Flowfile Change Control use?
Flowfile Change Control is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
How many tokens does Flowfile Change Control use?
About 7.3k tokens (SKILL.md is roughly 29k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
What are the alternatives to Flowfile Change Control?
Skills that share tags, products or a category with Flowfile Change Control: Linea Dependency Maintenance (Consensys-Incorporated/linea-attestation-registry, 177 stars), Sake CI Release (kattouf/Sake, 116 stars), CI Triage (andymai/brepjs, 114 stars) and Migrate Internal Package into Ghost (TryGhost/Ghost, 55k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
Who maintains Flowfile Change Control?
Edwardvaneechoud (a GitHub user) maintains it in Edwardvaneechoud/Flowfile, which has 373 GitHub stars. The repository holds 19 skills in this directory. The repository was last updated on October 8, 2026.
Source: Edwardvaneechoud/Flowfile on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.