In the first response of this skill, start with this line, only once:
sdd-release v1.0.0 · out/2026 · versão atual: https://github.com/robertodiasduarte/sdd-starter/releases/latest
Check what is going to go up, show once what goes to production and — only after the OK — integrate and publish.
The two rules that govern this skill
- Don't ask what you can find out. Investigate and decide; ask only about the ambiguous, with a recommendation. At the end, list what you assumed ("I assumed X because Y").
- Simple is not without a safety net. One extra step costs thirty seconds; a wrong publication costs the weekend. What gets cut is bureaucracy (elaborate changelog, new versioning, long report). Never what prevents publishing something broken, and never the moment when the user sees and approves what is going to go up.
Step 0 — Where am I
- Run
git rev-parse --show-toplevelandgit branch --show-current. If it is not a git repository, or if the current branch is the main one, stop and say: this skill runs from inside the folder of a front (created bysdd-new-sessionor bygit worktree add). - The main checkout is the first path of
git worktree list --porcelain. If there is<checkout principal>/sdd/ambiente.md, read and use (main branch, scenario, tests, deploy).
Step 1 — Find out what is missing (without asking)
Only what sdd/ambiente.md doesn't say:
git remote show origin
git log --oneline -20
git tag --list
ls .github/workflows/
And read: README.md, package.json (section scripts), Makefile, .github/workflows/*, CLAUDE.md,
AGENTS.md.
- Main branch — the remote's "HEAD branch".
- How the code reaches production — the most important discovery. Be honest:
- Automatic deploy: a workflow triggers on push to the main ⇒ the push IS the deploy.
- Manual deploy: there is a publication command (
npm run deploy,make deploy, a script). - None: the repository only stores code ⇒ "release" = integrate into the main, without pretending it was published.
- Tests (
npm test,pytest, a CI job) and syntax check for the files touched (node --check,php -l,python -m py_compile,tsc --noEmit). - Versioning (tags
v*,versionin thepackage.json,CHANGELOG.md). If there is none of that, don't invent: a project without a version doesn't get a version along with the release. - Scenario (the same as
sdd-new-session): direct commits to the main ⇒ A, Trunk-Based (ends in push to the main); PR merges ⇒ B, GitHub Flow (ends in PR to the main); version tags and branchesrelease/*orhotfix/*⇒ C, GitFlow (ends in PR todevelop) — the same criterion assdd-new-session. When in doubt between A and B, A. If there isdevelopnot remote but the criterion for C not being met, don't decide on your own: the last line of the OK block becomes "Can I publish to<recomendada>? (answerdevelopormainto switch)" — it remains only one question. The answered destination becomes the<alvo>of Phase 3:develop⇒ the front follows the path of scenario C (push the branch + PR todevelop), never the direct push to the main branch. - Integration branch — where this front goes in: the main branch in scenarios A and B,
developin C. From here on,<alvo>is it. Comparing or integrating a scenario C front against the main branch would take to production what is still in development.
Record what you found in sdd/ambiente.md of the main checkout (keys deploy, testes, sintaxe,
versionamento), creating the file in the format of sdd-new-session if it does not exist.
Phase 1 — Verify (on your own, without asking)
Everything here is local and reversible. In this order, stopping at the first failure:
- What exactly is going to be pushed — including what has not yet been committed:
git status --short --untracked-files=all— modified files and new (??, one per file, never the whole folder grouped) relative to the last commit. This is the commit list of Phase 3, including a file that was committed and then undone in the folder (it disappears from the summary below, but it needs to go into the commit for the undo to take effect).git diff --stat $(git merge-base origin/<alvo> HEAD)— compares the front's base with the working folder: it covers the front's commits and the changes not yet committed.- Don't use only
git diff origin/<principal>...HEAD: it ignores what has not been committed, and in a front with no commit it would show an empty summary — the user would approve something different from what is pushed. - A file that does not belong to this front? Stop and show — don't decide on your own what is left out.
Exception that is not part of the front and never goes into the commit: unversioned skill folders
(
.claude/skills/…,.agents/skills/…) — thesdd-new-sessioncopies them so the front works. - Something staged with a version different from the folder (the same file in
git diff --cached --name-onlyand ingit diff --name-only)? Stop and show: which of the two versions is pushed is the user's decision, and neither of the two can be discarded without them seeing. - Fingerprint of what is going to be pushed — save
git rev-parse HEAD(it fixes the history that the push will send), the result ofgit diff <base> | shasum, that ofgit diff --cached | shasum(what is already staged) and theshasumof each new file (??) — in PowerShell,Get-FileHash—, where<base>is$(git merge-base origin/<alvo> HEAD). It is what the OK approves; Phase 3 checks before committing. A commit rewritten after the OK changes theHEADeven if the final content is the same.
- Syntax of the touched files, with the tool from Step 1.
- Tests, if any exist. Red for everything: approving a diff with a broken test turns the OK into a rubber stamp.
- Leaking secret — in everything that will be pushed, not in the whole repository: the diff of the modified
files and the entire content of each new file (
??of thegit status), which does not appear in thegit diffbut will be committed. Look for an API key, token, password,.envbeing versioned by mistake: assignments such asAPI_KEY=,SECRET=,PASSWORD=,TOKEN=with a literal value, provider key prefixes and blocksPRIVATE KEY. And also in the front's history (git log -p <base>..HEAD: a key that entered one commit and left in the next disappears from the aggregated diff, but the push sends both commits. Found it in the history? Stop: rewriting history is the user's decision, never this skill's. A published key cannot be unpublished, not even by deleting the commit afterwards. - Did the base move?
git fetch origin <alvo>andgit rev-list --count HEAD..origin/<alvo>. Do not integrate now: agit mergehere would create a commit before the OK (and would reject the folder with uncommitted changes). Just record it: "the base moved N commits" goes in the OK block, and Phase 3 integrates the updated base and runs the tests again before any push.
If any item fails: stop, say which one failed, with file and reason, and do not continue. Do not fix it yourself
and do not ask for an OK "anyway". In that response do not mention the OK block or the question "Can I publish",
nor as a future step: end with what needs to be fixed and "then, run the sdd-release again".
Whoever reads the question at the end of the response understands that the OK is being requested.
Phase 2 — The only stopping point
Show a single block, in this format (fill it in; do not add questions):
**O que sobe**
<saída do --stat da Fase 1> + arquivos novos, pelo nome
**O que muda em produção:** <uma frase, em português — "muda o cálculo do relatório mensal da tela
inicial", não "altera handler.js">
**O push publica sozinho?** <sim, o workflow X publica ao receber o push na main | não: <por quê>>
**Verificações:** sintaxe <ok|pulada: motivo> · testes <ok|pulados: motivo> · segredo <nenhum, no
diff e nos arquivos novos> · base <atualizada | andou N commits: será integrada e testada de novo antes do push>
<só se não houver revisor humano:> Antes de responder, vale pedir à IA uma revisão do próprio código:
"isso quebra algo que já funcionava, expõe alguma senha, tem erro óbvio?"
**Posso publicar?** ← ou "Posso publicar na <alvo>?", no único caso do destino ambíguo (Passo 1)
- A missing check stated as missing is information; in silence, it is false security.
- The only question in the block is the last line, "Can I publish?" (or "Can I publish to
<alvo>?", if the destination became ambiguous in Step 1). The review suggestion is a sentence, not a question — turning it into "do you want me to review first?" creates a second stopping point, and two stops become a rubber stamp. - If something became ambiguous (which file belongs to the front), say inside this same block, before the last line — never stop twice.
- Without the OK, end here: no commit, merge or push.
Phase 3 — Publish (only after the OK)
- Is the folder still the one that was approved? Recompute the Phase 1 fingerprint. Different ⇒ something changed after the OK: stop, show what changed and ask for a new OK — never commit what has not been seen.
- Commit with the named files one by one — exactly those from the list of the
git statusfrom Phase 1, none other. Do not reset the index (it would erase the staged version that is not in the folder). After thegit add,git diff --cached --name-onlyit must be exactly that list — if another file appears staged, stop before the commit. After the commit,git status --shortempty — except for the unversioned skills folders, which are left out on purpose. Nevergit add -A, nevergit add -u: with two fronts open on the same machine, they drag the other's work. - Updated base, tested again. If the base moved:
git fetch origin <alvo>,git merge origin/<alvo>on the front, and run the tests again. Conflict or red test: stop before any push, say what broke — nothing was published. - Integrate by scenario, always from the front:
- A (Trunk-Based,
<alvo>= main):git push origin HEAD:<principal>. The push comes from the front, which contains exactly what was approved plus the remote base — never from the main checkout, where a local commit that nobody approved would go along. Rejected because the base moved (non-fast-forward/fetch first). Go back to item 3 (never force). Rejected for another reason (permission, protected branch)? Stop and show the error. - B (GitHub Flow):
git push -u origin <branch-da-frente>and open the PR to main — and stop there. Integration is the merge of the PR, after review. - C (GitFlow):
git push -u origin <branch-da-frente>and open the PR todevelop— and stop there. The front does not go directly to main.
- A (Trunk-Based,
- Manual deploy, if any, only from the already integrated and updated main — never from the branch of the
unpublished front. The deploy runs on a tree identical to what was published: in scenario A, the
front itself right after the accepted push — check
git status --porcelainempty andgit rev-parse HEADequal togit rev-parse origin/<principal>(aftergit fetch); if it does not match, stop. Never from the main checkout, which may have a local change or a commit that nobody approved. In scenarios B and C, hand over the deploy command to run after the PR is integrated; do not execute it beforehand. (With automatic deploy, the push to main itself already publishes.) - Confirm that it worked. Do not say "published" just because the command did not error. Is there CI? Look at the workflow result. Is there a URL? See if it responds. No way to confirm? Say so: "published, with no automatic verification available" is honest; "✅ all good" without having looked is not.
- Main checkout and cleanup, handed over as commands (from inside the worktree it cannot remove itself): in the main checkout,
git pull --ff-only— if it refuses, the local main has commits that were not published, and that is reported, not resolved by you; thengit worktree remove "<pasta>"(with quotes: the path may contain spaces) andgit branch -d <branch>(the lowercase-donly deletes what has already been integrated). In scenarios B and C, the cleanup comes after the PR merge.
Final answer in three lines: what went up, where it is, what is missing.
What does NOT go into this skill (and why)
- Detailed changelog — if the project already has
CHANGELOG.md, one line. If it doesn't, don't create one. - New versioning — a project that doesn't version today doesn't start versioning here.
- Long final report — three lines.
- Never
--force, under no circumstances. A refused push means the base has moved: fetch and integrate, never force over someone else's work (or over your own from yesterday). - Never a second stopping point — two stops become a rubber stamp: the person stops reading.
Why each rule exists
- The OK comes before the push: with automatic deploy, after the push there is no "before" to go back to.
- The
git addnames files: with two fronts open, the-Apublishes the one that isn't even finished. - The base is checked before and integrated after the OK: if another front got in first, the tests passed against a state that no longer exists — but integrating before the OK would create a commit that nobody approved. So: measure in Phase 1, integrate and test again in Phase 3, before the push.
- The push comes from the front, not from the main checkout: there may be a local commit there that didn't go through the OK.
- The summary covers the uncommitted: the commit happens after the OK, so what is approved must include what is still only in the folder.
- The skill runs from inside the front and cannot remove its own worktree at the end — the cleanup is the main checkout's job.
Part of the SDD Starter by RDD — https://github.com/robertodiasduarte/sdd-starter