TL;DR
What It Does
Unified entry point for ALL GitHub pushes — both Local (project repo) and Global (craft-framework-master-dev). Derives target repos dynamically from PROJECT_ID and MONOREPO_ROLE. Never hardcodes repo names. For Global pushes, delegates to CWK-045. For Local pushes, manages repo discovery, remote validation, archive detection, auto-fix of wrong remotes (with human confirmation), and PAT-based push. Supersedes CWK-038 for two-repo model pushes.
How It Works
Seven steps. (0) Read project config — extracts PROJECT_ID, MONOREPO_ROLE, and PROJECT_GITHUB_ORG; derives repo URLs. (1) Route by push type — global pushes gate on MASTER and delegate to CWK-045; local pushes continue. (2) Resolve local repo — applies override or derives from PROJECT_ID; human confirms target. (3) Validate remote — checks origin URL, auto-fixes mismatches with confirmation, detects archived repos. (4) Pre-push safety — verifies main branch, clean tree, ahead/behind counts. (5) Execute push — dry-run option; PAT URL push with error handling. (6) Report — target, branch, commits, remote fixes.
What To Expect
A successful Local push produces a push result showing the commit range pushed to the derived repo URL. A successful Global push produces the CWK-045 report (commit hash, diff stats, PAT scrub confirmation). Dry-run mode validates everything but skips the actual push.
Best Results When You
Have a valid session PAT. Know whether you want a Local or Global push. Have committed all changes (clean working tree). Are on the main branch.
Typical Time
2–5 minutes. Local pushes are faster than Global (no /tmp clone step).
Difficulty
Intermediate — the recipe handles repo derivation, remote validation, archive detection, and error recovery. You need to know your push type and have a PAT ready.
How To Start
This recipe replaces ad-hoc push commands and the older CWK-038 monorepo gate with a single, standardized push entry point. It derives everything from your project config — you never type a repo name. For Global pushes (framework files to craft-framework-master-dev), it delegates to CWK-045 after validating MASTER role. For Local pushes (project files to your project repo), it resolves the repo, validates the remote, runs safety checks, and pushes.
STEP 1Provide Push Details
Specify the push type (local or global), your PAT, and any additional parameters.
Available parameters
-
push_type
· string · required · options: local | global
Which repo to push to. “local” pushes to CFT-PROJ-CP-{NNN} derived from PROJECT_ID. “global” delegates to CWK-045 for craft-framework-master-dev (MASTER only).
-
pat
· string · required
GitHub Personal Access Token. Provided by human per session. Used in push URL, scrubbed after.
-
global_files
· list · optional
Files to push to Global repo. Required when push_type=“global”. Passed through to CWK-045.
-
commit_message
· string · optional
Commit message for Global push. Required when push_type=“global”. Passed through to CWK-045.
-
repo_name_override
· string · optional · default: None
Override the derived Local repo name. Use only when the GitHub repo doesn’t match PROJECT_ID convention. Ignored for global pushes.
-
github_org
· string · optional · default: from PROJECT_GITHUB_ORG or “CRAFTFramework”
GitHub organization. Rarely overridden.
-
dry_run
· boolean · optional · default: false
Validate everything but don’t push. Shows what would happen.
-
skip_archive_check
· boolean · optional · default: false
Skip the GitHub API archive status check. Use only if gh CLI is unavailable in sandbox.
Invocations
Local project push
#H->AI::Directive: (Execute CWK-046 with push_type="local", pat="ghp_…")
Global framework push
#H->AI::Directive: (Execute CWK-046 with push_type="global", pat="ghp_…", global_files=["framework/CFT-FWK-COOKBK-COWORK.txt"], commit_message="H090: Sync cookbook")
Dry run
#H->AI::Directive: (Execute CWK-046 with push_type="local", pat="ghp_…", dry_run=true)
Usage Examples
EXAMPLE 1Standard local push
User
Push the project to GitHub. Here’s the PAT.
Cat
Push Orchestrator — reading project config. PROJECT_ID: CFT-PROJ-CP-067. MONOREPO_ROLE: LOCAL-ONLY. Push type: local. Derived repo: CFT-PROJ-CP-067. Target: github.com/CRAFTFramework/CFT-PROJ-CP-067.git. Is this correct? [Y/N] … Origin matches — OK. Pre-push: on main, clean tree, 3 commits ahead. Pushing. Push complete: a1b2c3d..e4f5g6h main → main.
EXAMPLE 2Global push delegation
User
Push the updated cookbook to the Global repo.
Cat
Push Orchestrator — PROJECT_ID: CFT-PROJ-CP-060. MONOREPO_ROLE: MASTER. Push type: global. MASTER confirmed. Delegating to CWK-045 (Global File Push). Files: framework/CFT-FWK-COOKBK-COWORK.txt. CWK-045 result: Clone successful. Diff: +142 −38. Push complete: c610afe..4357a01. PAT scrubbed. /tmp/gfmd/ removed.
EXAMPLE 3Remote mismatch auto-fix
Cat
Push Orchestrator — PROJECT_ID: CFT-PROJ-CP-067. Derived repo: CFT-PROJ-CP-067. Checking origin… REMOTE MISMATCH: current origin points to github.com/CRAFTFramework/old-repo-name.git. Derived target: github.com/CRAFTFramework/CFT-PROJ-CP-067.git. Update origin? [Y/N] … Origin updated. Pre-push: on main, clean tree, 5 commits ahead. Pushing. Push complete: 1234abc..5678def main → main.
How AI Reads This Recipe
When this recipe is triggered, the AI provides unified push management for Local and Global repos. The AI should:
- Read project config. Extract PROJECT_ID, MONOREPO_ROLE, and PROJECT_GITHUB_ORG from the project implementation file. Derive local_repo_name from PROJECT_ID and construct repo URLs. If PROJECT_ID is not found, report error and stop.
- Route by push type. If push_type=“global”: verify MONOREPO_ROLE=MASTER (non-MASTER stops with CWK-039 redirect), verify global_files and commit_message provided, delegate to CWK-045. CWK-045 owns the rest of the global flow. If push_type=“local”: continue.
- Resolve local repo. Apply repo_name_override if provided, otherwise use derived name. Construct full repo URL. Ask human to confirm the push target — wait for confirmation.
- Validate remote. Check origin remote exists (add if missing with confirmation). Compare origin URL to derived URL (auto-fix mismatch with confirmation). Check repo accessibility — try gh CLI for archive status, fall back to git ls-remote. Stop on archived or not-found repos.
- Pre-push safety. Verify on main branch. Verify clean working tree (recommend CWK-005 if dirty). Fetch and report behind/ahead counts. Log commits to push.
- Execute push. If dry_run, report what would happen and stop. Otherwise push via PAT URL. Handle rejection (pull first), auth failure (new PAT), archive error, and unexpected errors.
- Report. Push target (derived, not hardcoded), branch, method, commit range, and any remote fixes applied. Update handoff with push details.
When To Use This Recipe
Use this recipe any time you need to push to GitHub — whether Local project files or Global framework files. It replaces direct git push commands and supersedes CWK-038 for two-repo model projects. Use for routine session-end pushes, post-checkpoint pushes, framework syncs (Global), and any time the project repo needs updating.
Do Not Use When
You need fine-grained git operations beyond push (use git directly). For Global-only pushes where you already know CWK-045 is the right recipe and want to skip orchestration overhead. For non-GitHub remotes (this recipe assumes GitHub URL patterns).
Recipe FAQ
Why not just use git push directly?
Direct git push requires remembering the repo URL, checking the remote, and handling errors manually. CWK-046 derives the repo from PROJECT_ID (never hardcoded), validates the remote, detects archived repos, auto-fixes mismatches, and provides structured error handling. It also gates Global pushes on MASTER role.
How does repo derivation work?
The recipe reads PROJECT_ID from the project implementation file (e.g., “CFT-PROJ-CP-067”), uses it as the local repo name, and constructs the GitHub URL using PROJECT_GITHUB_ORG (defaults to “CRAFTFramework”). The repo name is never hardcoded — it adapts to any CRAFT project.
What’s the relationship between CWK-046 and CWK-045?
CWK-046 is the orchestrator — it handles both Local and Global pushes. For Global pushes, it validates MASTER role and then delegates entirely to CWK-045, which handles the /tmp clone pattern, file mapping, commit, push, and PAT scrubbing. CWK-046 relays CWK-045’s results.
What happens if the remote doesn’t match?
The recipe compares the origin URL to the derived repo URL. If they differ (e.g., repo was renamed), it warns and offers to auto-fix with git remote set-url. This requires human confirmation — the recipe never changes remotes silently.
Does this work for any CRAFT project?
Yes. The recipe derives everything from PROJECT_ID and PROJECT_GITHUB_ORG — it is not hardcoded to any specific project. Connected projects use it for Local pushes; only MASTER projects can use it for Global pushes.
Version History
v1.00a — 2026-04-04
Initial creation at H107. Unified push management for Local and Global repos. Dynamic repo derivation from PROJECT_ID. CWK-045 delegation for Global pushes. Remote validation and auto-fix. Archive detection via gh CLI with git ls-remote fallback. Supersedes CWK-038 for two-repo model.