promote-to-main
Skill5 starsChanged 6 months agoMITView on GitHub
Promote integration to main with comprehensive changelog and PR creation. Use when user says "promote to main", "open promotion PR", "integration to main", or "create release PR to main". Runs pre-flight checks, change inventory, architecture diagrams, and creates a rich PR with release notes and traceability.
- Commits and pushes
In this repository23 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- .github/CLAUDE.mdCLAUDE.md
- tests/CLAUDE.mdCLAUDE.md
- audit-archSkill
- audit-bugsSkill
- audit-cohesionSkill
- audit-defense-standardsSkill
- audit-testsSkill
- chart-courseSkill
- check-bearingSkill
- design-guardsSkill
- elaborate-phaseSkill
- id-slopSkill
- make-arch-diagSkill
- make-reqSkill
- make-scenariosSkill
- render-recipeSkill
- review-promotionSkill
- update-architectureSkill
- update-reqsSkill
- update-specsSkill
- validate-auditSkill
- verify-diagSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
25 rules. About 0 are common, 13 are distinctive, and 12 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈13
Distinctive · estimate
This author's own choices. Worth a look.
12
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 30
When the develop branch is stable and ready to be promoted to main
- Distinctive: line 31
After feature PRs, bug fixes, and cleanup work have been collected and tested on develop
- Very specific: line 37
Create files outside .autoskillit/temp/promote-to-main/
- Distinctive: line 42
Use the Bash tool for file reads — use Read, Grep, Glob for all codebase inspection
- Very specific: line 43
Use gh pr create --body inline — always use --body-file
- Distinctive: line 46
Run ALL pre-flight checks before any analysis work
- Very specific: line 47
Check gh auth status before any GitHub operations
- Very specific: line 51
Use gh pr create --body-file (never inline body via --body)
- Distinctive: line 69
If either fails, try fetching:
- Distinctive: line 73
If still missing, print error to stderr and exit 1.
- Very specific: line 122
If .autoskillit/temp/promote-to-main/token_summary.md is non-empty, set TOKEN_SUMMARY_CONTENT to its contents and embed it in the PR body …
- Distinctive: line 124
If empty or absent (standalone invocation, no pipeline sessions in this cwd), omit the section — graceful degradation with no error.
- Distinctive: line 130
All three must pass before analysis proceeds.
- Very specific: line 139
No open PRs targeting integration with failing CI — gh pr list --base {batch_branch} --state open --json number,title,statusCheckRollup
- Very specific: line 174
No open PRs targeting integration with CHANGES_REQUESTED reviews — gh pr list --base {batch_branch} --state open --json number,title,reviews
- Very specific: line 188
Pre-flight gate: If any subagent returns "pass": false, report all failures in a clear summary table and exit 1 without proceeding to …
- Very specific: line 325
Development lens guard: Only select development if at least one changed file matches: pyproject.toml, Taskfile*, conftest.py, …
- Distinctive: line 338
CRITICAL: Do NOT output any prose status text between lens iterations.
- Distinctive: line 339
After completing all sub-steps for one lens, immediately begin sub-step 1 for the next lens.
- Very specific: line 375
Read the output from .autoskillit/temp/arch-lens-{lens-name}/ and extract the mermaid block(s).
- Distinctive: line 387
Commit categorization from Subagent 2A
- Very specific: line 420
If dry_run is true: skip to Output section.
- Very specific: line 426
If exit code non-zero: output pr_url = and exit successfully.
- Distinctive: line 441
Add label (optional, continue if fails):
- Distinctive: line 448
Always emit these structured output tokens as the final lines:
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Promote to Main
Orchestrate the integration-to-main promotion workflow. This skill discovers everything that changed on integration since it diverged from main, runs pre-flight quality checks, performs change inventory, generates architecture diagrams, synthesizes release notes, and creates a comprehensive promotion PR.
Arguments
/autoskillit:promote-to-main [batch_branch] [base_branch] [--dry-run]batch_branch(optional) — source branch to promote. Defaults tointegration.base_branch(optional) — target branch. Defaults tomain.--dry-run— generate the full PR body without creating a PR.
When to Use
- When the develop branch is stable and ready to be promoted to main
- After feature PRs, bug fixes, and cleanup work have been collected and tested on develop
- This is the final gate before changes land on main
Critical Constraints
NEVER:
- Create files outside
.autoskillit/temp/promote-to-main/ - Modify any source code — this skill is read-only analysis + PR creation
- Fail silently if
ghis unavailable — outputpr_url =(empty) and exit successfully - Push or merge anything — this skill only creates the PR
- Skip pre-flight checks — a failing pre-flight must block PR creation
- Use the Bash tool for file reads — use Read, Grep, Glob for all codebase inspection
- Use
gh pr create --bodyinline — always use--body-file
ALWAYS:
- Run ALL pre-flight checks before any analysis work
- Check
gh auth statusbefore any GitHub operations - Output
pr_url = <url>as a structured token (empty string when GitHub unavailable or dry-run) - Output
verdict = <value>as a structured token - Carry forward ALL
Closes #N,Fixes #N, andResolves #Nreferences from merged PR bodies - Use
gh pr create --body-file(never inline body via--body) pr_body_pathmust be an absolute path (prepend CWD)
Workflow
Phase 0: Setup
Step 0.1: Parse Arguments
Parse optional positional arguments and flags:
batch_branch— default"develop"if absent or emptybase_branch— default"main"if absent or emptydry_run—trueif--dry-runpresent in ARGUMENTS
Validate that both branches exist locally:
git rev-parse --verify {batch_branch} 2>/dev/null
git rev-parse --verify {base_branch} 2>/dev/nullIf either fails, try fetching:
git fetch origin {branch}:{branch} 2>/dev/nullIf still missing, print error to stderr and exit 1.
Step 0.2: Compute Divergence Point
git merge-base {base_branch} {batch_branch}Store as merge_base_sha.
Get commit count and timestamp:
git rev-list --count {merge_base_sha}..{batch_branch}
git show -s --format=%cI {merge_base_sha}Store as commit_count and merge_base_date.
Step 0.3: Retrieve Token Summary from Session Logs
Determine the pipeline working directory and self-retrieve token telemetry from disk. This aggregates token usage across all constituent PR sessions that ran in this pipeline working directory.
mkdir -p .autoskillit/temp/promote-to-main
python3 - <<'EOF' > .autoskillit/temp/promote-to-main/token_summary.md 2>/dev/null || true
import json, pathlib, sys
from autoskillit.pipeline.tokens import DefaultTokenLog
from autoskillit.pipeline.telemetry_fmt import TelemetryFormatter
from autoskillit.execution.session_log import resolve_log_dir
cfg_path = pathlib.Path(".autoskillit") / "temp" / ".hook_config.json"
kitchen_id = ""
if cfg_path.exists():
_cfg = json.loads(cfg_path.read_text())
if isinstance(_cfg, dict):
kitchen_id = _cfg.get("kitchen_id") or _cfg.get("pipeline_id", "")
log_root = resolve_log_dir("")
tl = DefaultTokenLog()
n = tl.load_from_log_dir(log_root, kitchen_id_filter=kitchen_id)
if n == 0:
sys.exit(0)
steps = tl.get_report()
total = tl.compute_total()
print(TelemetryFormatter.format_token_table(steps, total))
EOF- If
.autoskillit/temp/promote-to-main/token_summary.mdis non-empty, setTOKEN_SUMMARY_CONTENTto its contents and embed it in the PR body under## Token Usage Summary. - If empty or absent (standalone invocation, no pipeline sessions in this cwd), omit the section — graceful degradation with no error.
Phase 1: Pre-flight Checks (parallel, blocking)
Spawn three parallel Task subagents (model: sonnet) to validate promotion readiness. All three must pass before analysis proceeds. If any fails, report the failure clearly and exit 1. Do NOT create a PR when pre-flight fails.
Subagent 1A: CI and Branch Status
Check:
- CI is green on the integration branch — run
gh pr checksfor any open PR from integration, orgh run list --branch {batch_branch} --workflow tests.yml --limit 1 --json conclusion - The integration branch is not behind base — run
git rev-list --count {batch_branch}..{base_branch}to check if base has commits not in integration (if > 0, warn that a rebase may be needed) - No open PRs targeting integration with failing CI —
gh pr list --base {batch_branch} --state open --json number,title,statusCheckRollup
Return JSON:
{
"ci_status": "pass|fail|unknown",
"ci_details": "description of CI state",
"behind_base_by": 0,
"open_prs_with_failing_ci": [],
"pass": true
}Subagent 1B: Version Consistency
Check:
pyproject.tomlversion matchessrc/autoskillit/.claude-plugin/plugin.jsonversionuv lock --checkpasses (lockfile consistent)- The integration branch version is ahead of the base branch version
Return JSON:
{
"pyproject_version": "X.Y.Z",
"plugin_version": "X.Y.Z",
"versions_match": true,
"lockfile_consistent": true,
"version_ahead_of_base": true,
"pass": true
}Subagent 1C: Outstanding Review Items
Check:
- No open PRs targeting integration with
CHANGES_REQUESTEDreviews —gh pr list --base {batch_branch} --state open --json number,title,reviews - No
in-progresslabeled issues that might indicate incomplete work —gh issue list --label in-progress --state open --json number,title
Return JSON:
{
"prs_with_changes_requested": [],
"in_progress_issues": [],
"pass": true
}Pre-flight gate: If any subagent returns "pass": false, report all failures in a
clear summary table and exit 1 without proceeding to analysis. If ci_status is unknown,
treat as a warning (non-blocking) and note it in the report.
Phase 2: Change Inventory (parallel subagents)
Spawn four parallel Task subagents (model: sonnet).
Subagent 2A: Commit Categorization
Receive the output of:
git log {merge_base_sha}..{batch_branch} --format="%H %s"Categorize each commit into exactly one category based on its subject line:
rectify— subject contains "Rectify:" or "fix:" or "bugfix" (case-insensitive)feature— subject contains "Implementation Plan:", "feat:", "Add ", or introduces new capabilityinfra— subject contains CI, workflow, config, build, or infrastructure changestest— subject only touches test files (infer from "test" in subject ortests/paths)docs— subject contains "docs:", "README", or documentation-only changes
Extract PR numbers from patterns like (#123) in commit subjects.
Return JSON:
{
"categories": {
"rectify": [{"sha": "abc123", "title": "...", "pr_number": 495}],
"feature": [],
"infra": [],
"test": [],
"docs": []
},
"totals": {"rectify": 14, "feature": 13, "infra": 3, "test": 1, "docs": 1},
"category_summary": "14 fixes, 13 features, 3 infra"
}Subagent 2B: PR Discovery and Issue Linkage
Run:
gh pr list --base {batch_branch} --state merged --limit 200 --json number,title,author,mergedAt,body,headRefName,additions,deletions,labels,urlFilter to PRs merged after merge_base_date. If empty, fall back to commit-subject
discovery:
git log {merge_base_sha}..{batch_branch} --oneline --grep="(#" --format="%s"For each PR, extract Closes|Fixes|Resolves #N references (case-insensitive).
Deduplicate across all PRs. For each linked issue number, fetch details:
gh issue view {number} --json number,title,state,url,labels 2>/dev/nullBuild a traceability matrix: for each issue, identify which PR(s) close it.
Return JSON:
{
"prs": [{"number": 1, "title": "...", "author": "...", "labels": [], "url": "...", "additions": 0, "deletions": 0}],
"closing_refs": ["Closes #42", "Fixes #50"],
"linked_issue_numbers": [42, 50],
"issue_details": [{"number": 42, "title": "...", "state": "OPEN", "url": "...", "labels": ["recipe:implementation"]}],
"traceability": [{"issue_number": 42, "issue_title": "...", "pr_numbers": [491], "recipe_route": "implementation"}]
}Subagent 2C: File Lifecycle Tracking
Run:
git diff --name-only {base_branch}..{batch_branch}
git diff --diff-filter=A --name-only {base_branch}..{batch_branch}
git diff --diff-filter=M --name-only {base_branch}..{batch_branch}
git diff --diff-filter=D --name-only {base_branch}..{batch_branch}
git diff --diff-filter=R --name-only {base_branch}..{batch_branch}
git diff --stat {base_branch}..{batch_branch} | tail -1Return JSON:
{
"changed_files": ["..."],
"new_files": ["..."],
"modified_files": ["..."],
"deleted_files": ["..."],
"renamed_files": ["..."],
"diff_stat_summary": "185 files changed, 10013 insertions(+), 1164 deletions(-)"
}Subagent 2D: Migration and Schema Detection
Scan the diff for changes that require manual attention on merge. Check:
- Changes to
src/autoskillit/migrations/— new migration YAML notes - Changes to
src/autoskillit/recipe/schema.py— recipe schema modifications - Changes to
pyproject.toml— dependency additions/removals/version bumps - Changes to
src/autoskillit/config/defaults.yaml— config schema changes - Changes to
src/autoskillit/hooks/hooks.json— hook registration changes - Changes to
src/autoskillit/.claude-plugin/plugin.json— plugin metadata changes - Changes to
.github/workflows/— CI workflow modifications
For each detected change, provide a brief description of what changed and why it might need attention.
Return JSON:
{
"migration_changes": ["Added migration note for v0.3.2"],
"schema_changes": ["New RecipeStep field: optional"],
"dependency_changes": ["Added httpx>=0.27"],
"config_changes": ["New config key: github.staged_label"],
"hook_changes": ["New hook: pretty_output PostToolUse"],
"ci_changes": ["Updated tests.yml matrix"],
"attention_required": true,
"attention_summary": "Brief description of what needs human review"
}Phase 3: Architecture Diagrams
Step 3.1: Select Arch-Lens Lenses
Spawn a Task subagent (model: sonnet) with the changed_files list and this lens menu:
c4-container, concurrency, data-lineage, deployment, development,
error-resilience, module-dependency, operational, process-flow,
repository-access, scenarios, security, state-lifecycleReturn 1-3 lens names. Apply the same selection criteria as open-pr:
Development lens guard: Only select development if at least one changed file matches:
pyproject.toml, Taskfile*, conftest.py, .github/workflows/*, Makefile,
setup.cfg, setup.py, tox.ini, noxfile.py, or files under ci/.
For a promotion PR, prefer lenses that show the broadest architectural impact:
module-dependencyif changes span multiple packagesprocess-flowif workflow routing or state transitions changedc4-containerif new services, tools, or integrations were added
Step 3.2: Generate Arch-Lens Diagrams
For each selected lens, follow this exact sequence:
CRITICAL: Do NOT output any prose status text between lens iterations. After completing all sub-steps for one lens, immediately begin sub-step 1 for the next lens.
1. Write the PR context to a file using the Write tool:
- Path:
.autoskillit/temp/promote-to-main/pr_arch_lens_context_{YYYY-MM-DD_HHMMSS}.md - Content:
# PR Context — Integration to Main Promotion
This diagram is for a promotion PR merging the integration branch into main. Focus on the areas of the codebase affected by all accumulated changes. Do not create a generic whole-project diagram.
## New files (use star prefix on these nodes):
{list of new_files, or "None"}
## Modified files (use bullet prefix on these nodes):
{list of modified_files, or "None"}
## Deleted files:
{list of deleted_files, or "None"}
## Instructions:
- Focus exploration and the diagram on the architectural areas these files belong to
- Use star prefix on nodes representing new files/components
- Use bullet prefix on nodes representing modified files/components
- Mark deleted components with strikethrough or a X prefix
- Leave unchanged components unmarked (include only if needed for context/connectivity)
- This is a promotion PR — show the cumulative architectural impact of all changes2. Immediately call the Skill tool to load the arch-lens skill (e.g.,
/autoskillit:arch-lens-module-dependency).
3. Follow the loaded skill's instructions to generate the diagram.
Read the output from .autoskillit/temp/arch-lens-{lens-name}/ and extract the mermaid block(s).
Validate: if the block contains at least one star marker or bullet marker for
new/modified nodes, add to validated_diagrams. Otherwise discard.
Phase 4: Compose PR + Create PR
Step 4.1: Release Notes Synthesis
Spawn one Task subagent (model: sonnet) with results from Phase 2 ONLY (no domain analysis or quality assessment data). The subagent receives:
- Commit categorization from Subagent 2A
- PR and issue data from Subagent 2B
- File lifecycle from Subagent 2C
- Migration/schema detection from Subagent 2D
Return JSON:
{
"executive_summary": "3-5 sentence narrative of what this promotion brings, focused on change themes",
"highlights": ["top 3-5 most significant changes"],
"release_notes_md": "### New Features\n- ...\n### Bug Fixes\n- ...\n### Infrastructure\n...\n### Breaking Changes\n...\n### Attention Required\n..."
}Step 4.2: Write PR Body
Write to .autoskillit/temp/promote-to-main/pr_body_{YYYY-MM-DD_HHMMSS}.md
(relative to the current working directory).
Sections in order:
## Promotion: {batch_branch} to {base_branch}— executive summary + stats (diff_stat_summary,commit_count, PR count)### Highlights— from synthesis## Release Notes— from synthesis## Merged PRs— table (PR, Title, Author, Labels) from Subagent 2B## Linked Issues— table (Issue, Title, Status, Action) from Subagent 2B## Attention Required— from Subagent 2D (only ifattention_required=true)## Architecture Impact— validated mermaid diagrams from Phase 3- Closing references (
Closes #Nlines from Subagent 2B, one per line) ## Token Usage Summary— if TOKEN_SUMMARY_CONTENT non-empty- Footer:
<sub>Generated with Claude Code via AutoSkillit</sub>
Step 4.3: Create PR
If dry_run is true: skip to Output section.
Check GitHub availability:
gh auth status 2>/dev/nullIf exit code non-zero: output pr_url = and exit successfully.
Construct PR title using actual branch names:
Promote {batch_branch} to {base_branch} ({len(prs)} PRs, {len(linked_issue_numbers)} issues, {category_summary})
gh pr create \
--base {base_branch} \
--head {batch_branch} \
--title "{pr_title}" \
--body-file .autoskillit/temp/promote-to-main/pr_body_{timestamp}.mdCapture the PR URL as pr_url.
Add label (optional, continue if fails):
gh pr edit {pr_url} --add-label "promotion" 2>/dev/null || trueOutput
Always emit these structured output tokens as the final lines:
pr_body_path = {absolute path to .autoskillit/temp/promote-to-main/pr_body_{timestamp}.md}
pr_url = {pr_url, empty if dry-run or gh unavailable}
verdict = {created|dry_run|preflight_failed}
category_summary = {e.g., "14 fixes, 13 features, 3 infra"}Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

