'Stage, audit, commit, and submit uncommitted changes via Graphite, with parallel code-review agents. Use when user says "submit this", "ship it", or "commit and push", or has uncommitted work to turn into a PR. Requires uncommitted changes — a clean, already-committed branch needs only gt submit; amending an already-submitted branch is the gt-amend skill.'
Install
npx skillscat add kinginyellows/yellow-plugins/smart-submit Install via the SkillsCat registry.
What It Does
Conducts a systematic code quality audit of all uncommitted changes using
specialized agents, then creates a conventional commit and submits via
Graphite. Ensures no anti-patterns, secrets, or silent failures enter the
codebase.
When to Use
- User says "submit this", "ship it", or "commit and push", or has
uncommitted work to turn into a PR. - Requires uncommitted changes — a clean, already-committed branch needs
onlygt submit; amending an already-submitted branch is thegt-amend
skill instead.
Usage
Optional arguments:
--amend— Amend the current branch commit instead of creating a new branch--dry-run— Run the audit but skip the actual submission--no-verify— Skip the audit and submit directly (use with caution)--publish— Override draft mode: submit as published even ifsubmit.draft: truein.graphite.yml
The argument text provided after the skill name (if any) is available as
context for this invocation.
Phase 0: Read Convention File
Before any other work, check for a .graphite.yml convention file and parse
repo-level settings. Run a single Bash call:
REPO_TOP=$(git rev-parse --show-toplevel 2>/dev/null || echo ".")
GW_DRAFT=""
GW_MERGE_WHEN_READY=""
GW_RESTACK_BEFORE=""
GW_AUDIT_AGENTS=""
GW_SKIP_ON_DRAFT=""
GW_BRANCH_PREFIX=""
if command -v yq >/dev/null 2>&1 && \
yq --help 2>&1 | grep -qi 'jq wrapper\|kislyuk' && \
[ -f "$REPO_TOP/.graphite.yml" ]; then
yq_err=""
GW_DRAFT=$(yq -r '.submit.draft // ""' "$REPO_TOP/.graphite.yml" 2>/dev/null) || yq_err="submit.draft"
GW_MERGE_WHEN_READY=$(yq -r '.submit.merge_when_ready // ""' "$REPO_TOP/.graphite.yml" 2>/dev/null) || yq_err="${yq_err:+$yq_err, }merge_when_ready"
GW_RESTACK_BEFORE=$(yq -r '.submit.restack_before // ""' "$REPO_TOP/.graphite.yml" 2>/dev/null) || yq_err="${yq_err:+$yq_err, }restack_before"
GW_AUDIT_AGENTS=$(yq -r '.audit.agents // ""' "$REPO_TOP/.graphite.yml" 2>/dev/null) || yq_err="${yq_err:+$yq_err, }audit.agents"
GW_SKIP_ON_DRAFT=$(yq -r '.audit.skip_on_draft // ""' "$REPO_TOP/.graphite.yml" 2>/dev/null) || yq_err="${yq_err:+$yq_err, }skip_on_draft"
GW_BRANCH_PREFIX=$(yq -r '.branch.prefix // ""' "$REPO_TOP/.graphite.yml" 2>/dev/null) || yq_err="${yq_err:+$yq_err, }branch.prefix"
if [ -n "$yq_err" ]; then
printf '[gt-workflow] Warning: yq failed to parse fields: %s. Using defaults for those.\n' "$yq_err" >&2
else
printf '[gt-workflow] Convention file loaded: %s/.graphite.yml\n' "$REPO_TOP" >&2
fi
elif [ -f "$REPO_TOP/.graphite.yml" ]; then
printf '[gt-workflow] Warning: .graphite.yml exists but yq (kislyuk) is not installed. Using defaults.\n' >&2
printf '[gt-workflow] Install yq: pip install yq\n' >&2
fi
# Validate and clamp audit.agents to 1-3 range
if [ -n "$GW_AUDIT_AGENTS" ]; then
case "$GW_AUDIT_AGENTS" in
*[!0-9]*) printf '[gt-workflow] Warning: audit.agents value "%s" is not an integer. Using default 3.\n' "$GW_AUDIT_AGENTS" >&2; GW_AUDIT_AGENTS=3 ;;
esac
if [ "$GW_AUDIT_AGENTS" -lt 1 ] 2>/dev/null; then
printf '[gt-workflow] Warning: audit.agents=%s is below minimum. Using 1.\n' "$GW_AUDIT_AGENTS" >&2
GW_AUDIT_AGENTS=1
elif [ "$GW_AUDIT_AGENTS" -gt 3 ] 2>/dev/null; then
printf '[gt-workflow] Warning: audit.agents=%s exceeds maximum. Using 3.\n' "$GW_AUDIT_AGENTS" >&2
GW_AUDIT_AGENTS=3
fi
fi
# Validate branch.prefix against allow-list
if [ -n "$GW_BRANCH_PREFIX" ]; then
if ! printf '%s' "$GW_BRANCH_PREFIX" | grep -qE '^[a-z0-9][a-z0-9/_-]*$'; then
printf '[gt-workflow] Error: branch.prefix "%s" contains invalid characters. Using empty prefix.\n' "$GW_BRANCH_PREFIX" >&2
GW_BRANCH_PREFIX=""
fi
fiStore these values for use in subsequent phases. When a value is empty, use the
hardcoded default (draft=false, merge_when_ready=false, restack_before=true,
audit_agents=3, skip_on_draft=false, branch_prefix="").
Phase 1: Understand Current State
1. Check for Changes
Run these commands in parallel to understand the working tree and stack
position:
git status --shortgit diff --statgt log shortgt trunkIf there are no uncommitted changes, tell the user and exit.
2. Determine Branch Context
Check whether the current branch is trunk or a feature branch:
current=$(git branch --show-current)
trunk=$(gt trunk)
echo "current=$current trunk=$trunk"- If
current == trunk→ will usegt create <branch-name> -m "message"to
create a new branch - If
current != trunk→ will usegt modify -m "message"to update the
current branch - If
--amendargument was passed and on a feature branch → will usegt commit amendinstead
Phase 2: Audit (skip if --no-verify)
Skip-on-draft check: If $GW_SKIP_ON_DRAFT is true and $GW_DRAFT istrue (from .graphite.yml), skip the entire audit phase and proceed to
Phase 3.
Note: This check uses the config-derived values in
$GW_SKIP_ON_DRAFT
and$GW_DRAFTfrom.graphite.yml. CLI flags such as--publishaffect
the eventual submit mode, but they do not override the audit skip decision in
this phase.
0. Capture the Diff Once
Before spawning auditors, capture the full diff — staged and unstaged — so
all agents can use it without redundant calls. Use git diff HEAD rather
than a bare git diff: a bare git diff only shows unstaged changes, so
any changes the user staged with git add before invoking this skill would
be silently excluded from the audit while still ending up in the commit
(Phase 3 generates the commit message from git diff --cached and commits
the full index).
git diff HEADStore this output as $DIFF_OUTPUT (pass it as context to each agent below).
1. Run the Audit
Invoke the Skill tool with skill: "audit-review", passing $DIFF_OUTPUT
and $GW_AUDIT_AGENTS as context. (On Codex there is no Skill tool — read
the Codex-exposed audit-review skill and follow it directly with the same
context.) It runs the appropriate quick-code-review
/ quick-security-scan / quick-error-check prompts (1-3 of them, per$GW_AUDIT_AGENTS) and returns a CRITICAL / MINOR / CLEAN verdict with
file:line findings.
2. Gate Check
If audit-review reports a dispatch failure (an audit failed to run or
timed out), inform the user which audit is missing and ask whether to
proceed with partial results or abort.
IF CRITICAL ISSUES (secrets, production mocks, silent failures):
- Display blocking issues with file:line references
- Use AskUserQuestion (on Codex, which lacks that tool: present the same
options as a numbered list in your reply and wait for the user's answer)
to ask:- "Fix issues before submitting (Recommended)"
- "Submit anyway"
- "Abort"
- If "Fix issues" → stop and let the user fix them
- If "Abort" → stop entirely
IF MINOR ISSUES (TODOs, style, minor logic):
- Display warnings
- Proceed but note them in the output
IF CLEAN: Proceed automatically.
Phase 3: Stage & Commit
1. Stage Specific Files
IMPORTANT: Do NOT use git add . or git add -A. Instead, stage only the
specific changed files to avoid accidentally committing secrets, binaries, or
unrelated files.
# Get the list of changed/untracked files
git diff --name-only
git ls-files --others --exclude-standardReview the file list. Exclude any files that look like:
.env*files- Credential/key files
- Large binaries
- Build artifacts
Stage the appropriate files by name:
git add -- "<file1>" "<file2>"2. Generate Conventional Commit Message
Analyze the staged diff to determine the commit type and scope:
git diff --cached --stat
git diff --cachedGenerate a conventional commit message following this format:
feat:— new featurefix:— bug fixrefactor:— code restructuringdocs:— documentation changestest:— test additions/changeschore:— maintenance, config, dependencies
The message should be concise (under 72 chars for the subject line). Include a
body if the changes are complex.
Take the Linear ID only from the last path segment of the branch name, which must start with [A-Z]{2,5}-[0-9]{1,6} followed by - or the end of the name, or from the stack item's Linear: field; ignore IDs mentioned anywhere else.
When an ID qualifies, end the body with Part of <ISSUE-ID>, and write Closes <ISSUE-ID> instead only when the user confirms through AskUserQuestion that
this change completes the issue (a stack built bottom-up would otherwise close
the issue from its first branch). Skip the line when no ID qualifies. Graphite
turns the commit body into the PR description, and the merge queue builds the
squash commit from it; the closing word is how Linear moves the issue to Done
even though the queue closes the PR instead of merging it. Keep the line when--amend rewrites the message.
3. Create Commit via Graphite
If on trunk (creating new branch):
Derive the branch name from the commit type and a short slug (e.g.,feat/add-user-auth, fix/null-pointer-crash). If $GW_BRANCH_PREFIX is set,
prepend it to the branch name:
gt create "<GW_BRANCH_PREFIX><branch-name>" -m "<conventional commit message>"For example, with branch.prefix: "agent/" and slug feat/add-user-auth, the
branch name becomes agent/feat/add-user-auth.
If on feature branch (adding to existing):
gt modify -m "<conventional commit message>"If --amend (modifying current branch):
gt commit amend -m "<conventional commit message>"Phase 4: Submit
1. Push to GitHub
If --dry-run was provided, skip this step and do not run gt submit; instead,
only simulate the submission and proceed to the result summary without making
any remote changes.
Build the submit command with convention file flags. First, if $GW_RESTACK_BEFORE
is true, run restack as a separate preceding command:
gt stack restackThen submit with flags based on .graphite.yml values:
gt submit --no-interactiveAppend flags to the submit command (only if set and non-empty):
- If
$GW_DRAFTistrue(and no explicit--publishargument): add--draft - If
$GW_MERGE_WHEN_READYistrue: add--merge-when-ready
After submitting, confirm the new stack state:
gt log shortgt prOutput a summary:
- Commit message used
- Branch created/amended
- PR link
- Stack visualization
- Any audit warnings that were noted
Success Criteria
- All uncommitted code audited by 1-3 specialized agents (unless
--no-verify) - No critical issues committed
- Files staged individually (no blanket
git add .) - Conventional commit message generated from diff analysis
- Graphite stack created/updated and submitted (or a dry-run summary produced
when--dry-runis used) - User provided with PR link and stack context