swain-sync
Fetch upstream, merge (worktree) or rebase (tracked branch), stage all changes, enforce gitignore hygiene, run ADR compliance checking on modified artifacts, rebuild stale artifact indexes, generate a descriptive commit message from the diff, commit, and push to the current branch's upstream. Handles merge conflicts by preferring local changes for config/project files and upstream for scaffolding.
What this skill does
<!-- swain-model-hint: sonnet, effort: low -->
<!-- session-check: SPEC-121 -->
Before proceeding with any state-changing operation, check for an active session:
```bash
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
bash "$REPO_ROOT/.agents/bin/swain-session-check.sh" 2>/dev/null
```
If the JSON output has `"status"` other than `"active"`, inform the operator: "No active session — start one with `/swain-init`?" Proceed if they dismiss.
Run through the following steps in order without pausing for confirmation unless a decision point is explicitly marked as requiring one.
Delegate this to a sub-agent so the main conversation thread stays clean. Include the full text of these instructions in the agent prompt, since sub-agents cannot read skill files directly.
## Step 1 — Detect worktree context and fetch/rebase upstream
First, detect whether you are running in a git linked worktree:
```bash
GIT_COMMON=$(git rev-parse --git-common-dir)
GIT_DIR=$(git rev-parse --git-dir)
IN_WORKTREE=$( [ "$GIT_COMMON" != "$GIT_DIR" ] && echo "yes" || echo "no" )
REPO_ROOT=$(git rev-parse --show-toplevel)
TRUNK=$(bash "$REPO_ROOT/.agents/bin/swain-trunk.sh")
```
`IN_WORKTREE=yes` means the current directory is inside a linked worktree (e.g., `.worktrees/agent-abc123`). Use this flag in Steps 3, 6, and the session bookmark step.
Next, check whether the current branch has an upstream tracking branch:
```bash
git --no-pager rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/null
```
If there is an upstream, fetch and rebase to incorporate upstream changes BEFORE staging or committing:
```bash
git fetch origin
```
If there are local changes (dirty working tree), stash them first. Use a targeted pop to avoid interfering with stashes from other worktrees (SPEC-252: shared stash is a collision vector):
```bash
BRANCH=$(git rev-parse --abbrev-ref HEAD)
STASH_MSG="swain-sync: auto-stash [$BRANCH]"
git stash push -m "$STASH_MSG"
STASH_REF=$(git stash list --format='%gd %s' | grep -F "$STASH_MSG" | head -1 | cut -d' ' -f1)
git --no-pager rebase origin/$BRANCH
git stash pop "$STASH_REF"
```
If the rebase has conflicts after stash pop, abort and report:
```bash
git rebase --abort # if rebase itself conflicts
git stash pop "$STASH_REF" # recover stashed changes (targeted, not bare pop)
```
Show the user the conflicting files and stop. Do not force-push or drop changes.
If there is no upstream (`@{u}` returns an error) **and** `IN_WORKTREE=yes`, the worktree branch has no remote tracking counterpart. Merge the trunk branch to combine the agent's changes with whatever landed since the branch was created:
```bash
git fetch origin
git merge "origin/$TRUNK" --no-edit
```
If the merge has conflicts, report them and stop. Do not attempt to auto-resolve.
If `origin` cannot be fetched, skip fetch/rebase and proceed to Step 2.
If there is no upstream **and** `IN_WORKTREE=no` (main worktree, new branch), skip this step entirely.
## Step 2 — Survey the working tree
```bash
git --no-pager status
git --no-pager diff # unstaged changes
git --no-pager diff --cached # already-staged changes
```
If the working tree is completely clean and there is nothing to push, report that and stop.
## Step 3 — Stage changes
Identify files that look like secrets (`.env`, `*.pem`, `*_rsa`, `credentials.*`, `secrets.*`). If any are present, warn the user and exclude them from staging.
**If there are 10 or fewer changed files** (excluding secrets), stage them individually:
```bash
git add file1 file2 ...
```
**If there are more than 10 changed files**, stage everything and then unstage secrets:
```bash
git add -A
git reset HEAD -- <secret-file-1> <secret-file-2> ...
```
## Step 3.5 — Gitignore check
Before committing, verify `.gitignore` hygiene. **This step is blocking** — if relevant patterns are missing, stop and require the user to fix `.gitignore` before proceeding.
### 1. Check existence
If no `.gitignore` file exists in the repo root:
> STOP: No `.gitignore` file found. Create one before committing — without it, secrets, build artifacts, and OS files can enter git history.
> Minimal starting point: `curl -sL https://www.toptal.com/developers/gitignore/api/macos,linux,node,python > .gitignore`
**Stop execution.** Do not commit.
### 2. Detect relevant patterns
Check which patterns are *relevant* to this repo, based on what actually exists on disk:
| Pattern | Relevant if |
|---------|-------------|
| `.env` | `.env.example` exists, OR any untracked/tracked `.env` or `.env.*` file is present (excluding `.env.example`), OR `dotenv` appears in `package.json` or `requirements.txt` |
| `node_modules/` | `package.json` exists in the repo root or any subdirectory |
| `__pycache__/` | any `*.py` file exists in the repo |
| `*.pyc` | same as `__pycache__/` |
| `.DS_Store` | repo is on macOS (`uname` returns `Darwin`) |
For each relevant pattern, check if `.gitignore` contains it (exact match or substring). Collect missing ones.
### 3. Decide whether to block
- If **no relevant patterns are missing**: this step is silent. Continue to Step 3.7.
- If **any relevant patterns are missing**: stop and report:
> STOP: `.gitignore` is missing patterns relevant to this repo:
> - `.env` — `.env.example` found; without this, a local `.env` file could be committed
> - `node_modules/` — `package.json` found
>
> Add the missing patterns before committing:
> echo ".env" >> .gitignore
> echo "node_modules/" >> .gitignore
>
> To permanently suppress a specific pattern check (intentional omission), add a comment to `.gitignore`:
> # swain-sync: allow .env
**Stop execution.** Do not commit until the user resolves this.
### 4. Skip logic
If `.gitignore` contains `# swain-sync: allow <pattern>` for a given pattern, treat that pattern as intentionally omitted and do not flag it.
## Step 3.7 — ADR compliance check
If modified files include any swain artifacts (`docs/spec/`, `docs/epic/`, `docs/vision/`, `docs/research/`, `docs/journey/`, `docs/persona/`, `docs/runbook/`, `docs/design/`, `docs/train/`), run an ADR compliance check against each modified artifact:
```bash
bash "$REPO_ROOT/.agents/bin/adr-check.sh" <artifact-path>
```
For each artifact with findings (exit code 1 = advisory RELEVANT findings, exit code 2 = actionable DEAD_REF or STALE findings), collect the output and present a single consolidated warning after all checks complete:
> ADR compliance: N artifact(s) have findings that may need attention.
> <condensed findings summary>
This step is **advisory** — it warns but never blocks the commit. Continue to Step 4 regardless.
If the `adr-check.sh` script is not found or fails with exit code 3, skip silently — the check is only available in repos with swain-design installed.
## Step 3.8 — Design drift check
Run `design-check.sh` with no arguments (scan all active DESIGNs) to detect design-to-code drift:
```bash
bash "$REPO_ROOT/.agents/bin/design-check.sh" 2>/dev/null
```
For each DESIGN with findings (STALE or BROKEN `sourcecode-refs`), collect the output and present a single consolidated warning after the check completes:
> Design drift: N DESIGN(s) have stale or broken sourcecode-refs.
> <condensed findings summary>
This step is **advisory** — it warns but never blocks the commit. Continue to Step 4 regardless.
If the `design-check.sh` script is not found or fails with exit code 2, skip silently — the check is only available in repos with swain-design installed.
## Step 3.85 — README reconciliation (ADR-023)
If README.md exists and the staged changes include artifacts or code that could affect README claims, run a lightweight drift check:
```bash
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
if [ -f "$REPO_ROOT/README.md" ]; then
STAGED_ARTIFACTS=$(git diff --cached --name-only | grep -E "^docs/(spec|epic|vision|design)/" || true)
STAGED_CODE=$(git diff --cached --name-only | grep -vE Related in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.