src/autoskillit/skills_extended/promote-to-main/SKILL.md
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.
npx skillsauth add talont-org/autoskillit promote-to-mainInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
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.
/autoskillit:promote-to-main [batch_branch] [base_branch] [--dry-run]
batch_branch (optional) — source branch to promote. Defaults to develop.base_branch (optional) — target branch. Defaults to main.--dry-run — generate the full PR body without creating a PR.NEVER:
{{AUTOSKILLIT_TEMP}}/promote-to-main/gh is unavailable — output pr_url = (empty) and exit successfullygh pr create --body inline — always use --body-filerun_in_background: true is prohibited)ALWAYS:
gh auth status before any GitHub operationspr_url = <url> as a structured token (empty string when GitHub unavailable or dry-run)verdict = <value> as a structured tokenCloses #N, Fixes #N, and Resolves #N references from merged PR bodiesgh pr create --body-file (never inline body via --body)pr_body_path must be an absolute path (prepend CWD)When context is exhausted mid-execution, temp files may be written but the PR may
not yet be created. The recipe routes to on_context_limit (typically escalate_stop),
bypassing the normal completion protocol.
Before emitting structured output tokens:
pr_url = (empty) if the PR was not successfully createdverdict = preflight_failed to signal an incomplete runParse optional positional arguments and flags:
batch_branch — default "develop" if absent or emptybase_branch — default "main" if absent or emptydry_run — true if --dry-run present in ARGUMENTSValidate that both branches exist locally:
git rev-parse --verify {batch_branch} 2>/dev/null
git rev-parse --verify {base_branch} 2>/dev/null
If either fails, try fetching:
git fetch origin {batch_branch}:{batch_branch} 2>/dev/null
If still missing, print error to stderr and exit 1.
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.
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
{{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 under ## Token Usage Summary.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.
Check:
gh pr checks for any open PR from
integration, or gh run list --branch {batch_branch} --workflow tests.yml --limit 1 --json conclusiongit 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)gh pr list --base {batch_branch} --state open --json number,title,statusCheckRollupReturn JSON:
{
"ci_status": "pass|fail|unknown",
"ci_details": "description of CI state",
"behind_base_by": 0,
"open_prs_with_failing_ci": [],
"pass": true
}
Check:
pyproject.toml version matches src/autoskillit/.claude-plugin/plugin.json versionuv lock --check passes (lockfile consistent)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
}
Check:
CHANGES_REQUESTED reviews —
gh pr list --base {batch_branch} --state open --json number,title,reviewsin-progress labeled issues that might indicate incomplete work —
gh issue list --label in-progress --state open --json number,titleReturn 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.
Spawn four parallel Task subagents (model: sonnet).
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 or tests/ paths)docs — subject contains "docs:", "README", or documentation-only changesExtract 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"
}
Run:
gh pr list --base {batch_branch} --state merged --limit 200 --json number,title,author,mergedAt,body,headRefName,additions,deletions,labels,url
Filter 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 $ISSUE_NUMBER --json number,title,state,url,labels 2>/dev/null
Build 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"}]
}
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 -1
Return JSON:
{
"changed_files": ["..."],
"new_files": ["..."],
"modified_files": ["..."],
"deleted_files": ["..."],
"renamed_files": ["..."],
"diff_stat_summary": "185 files changed, 10013 insertions(+), 1164 deletions(-)"
}
Scan the diff for changes that require manual attention on merge. Check:
src/autoskillit/migrations/ — new migration YAML notessrc/autoskillit/recipe/schema.py — recipe schema modificationspyproject.toml — dependency additions/removals/version bumpssrc/autoskillit/config/defaults.yaml — config schema changessrc/autoskillit/hooks/hooks.json — hook registration changessrc/autoskillit/.claude-plugin/plugin.json — plugin metadata changes.github/workflows/ — CI workflow modificationsFor 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"
}
Architecture diagrams are generated via arch-lens skills. Using ONLY classDef styles from the mermaid skill (no invented colors).
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-lifecycle
Return 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-dependency if changes span multiple packagesprocess-flow if workflow routing or state transitions changedc4-container if new services, tools, or integrations were addedFor 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:
{{AUTOSKILLIT_TEMP}}/promote-to-main/pr_arch_lens_context_{YYYY-MM-DD_HHMMSS}.md# 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 changes
2. 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.
Spawn one Task subagent (model: sonnet) with results from Phase 2 ONLY (no domain analysis or quality assessment data).
The subagent receives:
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..."
}
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 if attention_required=true)## Architecture Impact — validated mermaid diagrams from Phase 3Closes #N lines from Subagent 2B, one per line)## Token Usage Summary — if TOKEN_SUMMARY_CONTENT non-empty<sub>Generated with Claude Code via AutoSkillit</sub>If dry_run is true: skip to Output section.
Check GitHub availability:
gh auth status 2>/dev/null
If exit code non-zero: output pr_url = and exit successfully.
Construct PR title using actual branch names:
Promote {batch_branch} to {base_branch} ($PR_COUNT PRs, $ISSUE_COUNT 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.md
Capture the PR URL as $PR_URL.
Add label (optional, continue if fails):
gh pr edit $PR_URL --add-label "promotion" 2>/dev/null || true
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 on dry-run or when GitHub CLI is unreachable}
verdict = {created|dry_run|preflight_failed}
category_summary = {e.g., "14 fixes, 13 features, 3 infra"}
development
Generate YAML recipes for .autoskillit/recipes/. Use when user says "make script skill", "generate script", "script a workflow", "write a script", "create a script", "new recipe", "write a pipeline", or when loaded by other skills for script formatting.
data-ai
Create Uncertainty Representation visualization planning spec showing error bar definitions, distribution-aware alternatives, and multi-seed variance protocols. Statistical lens answering "How is uncertainty honestly represented?"
data-ai
Create Temporal Dynamics visualization planning spec showing axis scaling (linear vs log), smoothing disclosure, epoch/step alignment, run aggregation (mean + variance bands), early-stopping markers, and wall-clock vs step-count x-axis. Temporal lens answering "Are training dynamics shown clearly and honestly?"
data-ai
Create Narrative Story Arc visualization planning spec showing visual consistency across the report (same color = same model everywhere), logical figure progression, redundant figure detection, and narrative dependency between figures. Narrative lens answering "Do the figures tell a coherent story across the report?"