---
name: baldart-push
effort: medium
description: "Guidance for contributing local framework improvements upstream to the BALDART repository. Use when the user says /baldart-push, 'contribuisci al framework', 'push del framework', 'manda upstream', 'pusha le modifiche al framework', or wants to share local improvements made to .framework/. The skill walks the user through the contribution flow and hands off to `npx baldart push` (which must run in the user's terminal because the CLI is interactive). Never pushes baldart.config.yml, .baldart/overlays/, or .claude/hooks/ customizations — only generic framework payload."
contamination_scan: skip
---

# /baldart-push — Contribute upstream

Guide the user through a safe, contamination-aware contribution flow that
pushes local improvements made under `.framework/` (or new consumer-authored
skills in `.claude/skills/`) back to the BALDART upstream repository —
without leaking any project-specific path, identity, stack, or workflow
opinion.

## Execution model — IMPORTANT

This is a **guidance skill**, not an executor. The CLI command
`npx baldart push` is interactive (`inquirer` prompts) and **cannot run
through Claude Code's Bash tool** because there is no TTY: prompts would
hang silently. The skill therefore:

1. Runs *read-only* preview commands you CAN execute (`npx baldart version --offline`, contamination scans via the Node API).
2. Explains what each interactive prompt will ask.
3. **Asks the user to run `npx baldart push` in their own terminal.**
4. After they return with the output (or paste a transcript), narrates the result and suggests next steps.

If the user insists on running it through Claude, refuse politely and link to this section — running an interactive CLI without a TTY will simply hang. The configure flow works the same way.

## When to use

- The user invokes `/baldart-push`.
- The user says "contribuisci al framework", "pusha le modifiche al framework",
  "manda upstream", "contribute these improvements".
- The user finished a session in which they edited `.framework/.../*.md`,
  `framework/agents/*.md`, or wrote a new skill in `.claude/skills/<name>/`
  that should become a framework skill.

## When NOT to use

- The user wants to commit code **inside the consumer repo** (use git directly).
- The user wants to install / update the framework (use `/baldart-update` /
  `npx baldart update`).
- The user wants to author a project-specific overlay (it lives in
  `.baldart/overlays/`, never pushed upstream).
- The user wants to author a project-specific skill that is NOT meant for
  the framework — they keep it under `.claude/skills/<name>/`, do not run
  this skill.

## Project Context

**Reads from `baldart.config.yml`:** none (this skill operates on the
framework's own contents, not the consumer's project context).
**Gated by features:** none.
**Overlay:** loads `.baldart/overlays/baldart-push.md` if present — typical
overlay content: extra contamination rules specific to the consumer's domain
(e.g. internal codenames, private endpoints).
**On missing/empty keys:** not applicable.

## Effort

**Baseline:** `effort: medium` (frontmatter). **Inline override:** pass
`effort=<low|medium|high|xhigh|max>` anywhere in the invocation to scale
reasoning depth for this run — detect it once at kickoff and strip the token
before consuming user input. Level→behavior mapping, parsing contract, and
precedence caveats: `framework/agents/effort-protocol.md`.


## Hard rules

1. **NEVER push** `baldart.config.yml`, anything under `.baldart/`, anything
   under `.claude/hooks/` that is not the `.template` file. The CLI's triage
   already excludes these; do not override the CLI on this point.
2. **NEVER bypass the contamination scan**, not even on user request. If the
   user wants to force a token through, they choose "keep & force" in the
   per-file review — that is the only acceptable bypass.
3. **NEVER skip the auto-pull-then-push step**. If the remote is ahead, the
   CLI runs `update` first. If that update has conflicts, the push aborts
   and the user resolves them by hand.
4. **NEVER commit secrets**. The CLI hard-blocks on patterns matching AWS
   keys, bearer tokens, API keys, PEM private key headers. If the CLI blocks,
   the skill MUST surface that to the user and STOP.
5. **NEVER fabricate a CHANGELOG entry beyond what the diff supports.** The
   description the skill solicits from the user is one line; everything else
   (Added/Changed/Removed file lists) comes from the diff itself.
6. **Always show the user the current framework version + remote drift**
   BEFORE asking any other question. This is the centralised-versioning
   requirement: the user must always know which version they are on and what
   the push will bump it to.

## Workflow

### Step 0 — Version snapshot

Before doing anything else, run:

```
npx baldart version
```

and surface its output to the user. They should see:

- Installed framework version (with install date)
- Remote drift (ahead / behind / clean)
- Uncommitted improvements count
- Last push (version + date)

If the user is on a stale version with `behind > 0`, warn them that the
push step will auto-update first (this is expected, not an error).

### Step 1 — Pre-flight scan (read-only, safe to run)

Before handing off, optionally surface what the CLI WILL find. This is purely
informational — no commits, no autofix.

Diff preview:
```bash
git diff --name-status origin/main..HEAD -- .framework/
```

Contamination preview (Node one-liner — does not modify anything):
```bash
node -e "
const fs=require('fs'), path=require('path'), c=require('.framework/src/utils/contamination');
const { execSync } = require('child_process');
const files = execSync('git diff --name-status origin/main..HEAD -- .framework/').toString().trim().split('\n').filter(Boolean).map(l => l.split('\t').pop());
let totals = { autofixable:0, requiresDecision:0, blocking:0 };
for (const f of files) {
  if (!fs.existsSync(f) || fs.lstatSync(f).isDirectory()) continue;
  const { findings } = c.scan(fs.readFileSync(f, 'utf8'));
  const s = c.summarise(findings);
  totals.autofixable += s.autofixable;
  totals.requiresDecision += s.requiresDecision;
  totals.blocking += s.blocking;
  if (s.total) console.log(f, JSON.stringify(s));
}
console.log('TOTAL', JSON.stringify(totals));
"
```

Use the preview to:

- Spot **blocking** findings early (secrets) — fix BEFORE running push.
- Show the user how much manual review is coming (requiresDecision count).
- Confirm the new-skill list (`ls -d .claude/skills/*/ | xargs -I{} sh -c 'test ! -L "{}" && echo {}'`).

### Step 2 — Hand off to the user's terminal

Ask the user to run:

```bash
npx baldart push
```

**in their own terminal** (NOT through Claude Code Bash). The CLI will:

1. Pre-flight + framework existence check.
2. Auto-pull when remote is ahead (calls `baldart update`).
3. Pending-files discovery in `.framework/`.
4. New-skill discovery in `.claude/skills/` — prompts which to contribute.
5. Triage (pushable / blocked / docs).
6. Contamination scan → autofix paths → review identity/stack tokens.
7. Classification prompt (suggests MAJOR/MINOR/PATCH from diff).
8. Description prompt (1-line — used in commit + tag annotation + CHANGELOG).
9. VERSION bump + CHANGELOG entry insertion (auto).
10. Subtree push + annotated tag push.
11. `.baldart/state.json` update.

Do NOT re-implement this logic. The CLI is the source of truth.

### Step 3 — Explain each prompt BEFORE the user sees it

So the user knows what to choose, narrate the prompts that the CLI will pose:

- "5 autofixable findings" → "the CLI found 5 hardcoded paths I can safely
  replace with `${paths.X}` references. Confirming will rewrite those lines
  in place; the diff stays clean."
- "Review project-specific tokens" → "the CLI found tokens like `Neo-Brutalism`
  that are project opinions. For each file, decide: **keep & force push**
  (the token is generic enough in context), **skip the file** (leave it out
  of the push — for newly-added files the CLI runs `git rm`; for modifications
  it restores from `origin/main`), or **abort everything** (the CLI surfaces
  the rollback SHA so you can `git reset --hard <sha>` and clean up by hand,
  e.g. by moving the project-specific content into `.baldart/overlays/`)."
- "Suggested classification" → "the CLI inferred this from the diff: added
  files → MINOR, only modified → PATCH, deleted → MAJOR. Confirm or override."

### Step 4 — Post-push report

After the user returns with the CLI output, summarise back to them:

- Version bump that happened (old → new).
- One-line description.
- Number of files pushed.
- Any new skills contributed.
- Tag pushed.
- Updated state file (`.baldart/state.json`).

Suggest the next step:

```
Verify on GitHub:  https://github.com/<repo>/releases/tag/v<new>
Update local installs in other consumer repos:  npx baldart update
```

## Failure modes

| Symptom | Cause | What you do |
|---|---|---|
| CLI hard-blocks on "secret detected" | Pattern looks like AWS key / bearer / PEM | STOP. Surface the offending line to the user. Ask them to remove it from `.framework/` and re-run. Do not attempt to bypass. |
| `baldart update` (called automatically) fails with conflict | Remote diverged | STOP. Print the conflict files. The user resolves manually, commits, then re-runs `/baldart-push`. |
| User refuses autofix | Authoring decision | Continue, but warn that hardcoded paths in upstream will likely be rejected on review. |
| User aborts during the per-file review | Authoring decision | Surface that the autofix commits are still in their working copy. They can undo via `git reset HEAD~1` if they want to discard them. |
| Tag push fails (auth issue) | Subtree push went through but tag did not | Surface the tag name. User pushes manually with `git push origin v<X.Y.Z>`. The release is recoverable. |
| `state.json` write fails | Disk / permissions | Non-fatal. Surface as a warning; the rest of the push succeeded. |

## Why this skill exists

Before v3.1.0, contributing back required: remembering to update VERSION by
hand, hand-writing a CHANGELOG entry, classifying severity without
suggestion, running `git tag` manually, and — most importantly — relying on
human discipline to NOT push hardcoded fidelity-app paths into the upstream
framework. The first two are tedium; the last is the single biggest source
of v2.x → v3.0.0 cleanup work.

This skill makes the contribution loop:

1. **Fast** (auto bump, auto CHANGELOG, auto tag).
2. **Safe** (contamination scan + autofix gate before any commit).
3. **Visible** (centralised versioning via `state.json`, version-aware UI).
4. **Conversational** (the user understands every step, has a chance to
   abort, and the result is auditable).
