# Branch Sync And Push Safety > Nota interna del proyecto no-mistakes. Se usa al cambiar la sincronización de la rama local, la recuperación de custodia, el binding del head tras el review, el rebase o la seguridad del force-push, cuyo objetivo es no perder código. Fuente: https://skillsagentes.com/skills/kunchenguid/no-mistakes/branch-sync-and-push-safety Markdown: https://skillsagentes.com/skills/kunchenguid/no-mistakes/branch-sync-and-push-safety.md Repositorio: https://github.com/kunchenguid/no-mistakes Autor: kunchenguid Licencia: MIT Actualizado: hace 3 días Coste de contexto: 31 tok instalada, 2.5k tok al activarse, 2.5k tok con todos los archivos del bundle Bundle: 1 archivo, 10 KB Permisos que pide: ninguno declarado ## Instalación Un skill son archivos markdown: los mismos archivos valen para cualquier agente y lo único que cambia es el directorio de destino, es decir la bandera `--agent`. Añade `-g` para instalarlo en todos los proyectos de la máquina. ```bash # Claude Code npx -y skills add kunchenguid/no-mistakes --skill branch-sync-and-push-safety --agent claude-code # Cursor npx -y skills add kunchenguid/no-mistakes --skill branch-sync-and-push-safety --agent cursor # Codex npx -y skills add kunchenguid/no-mistakes --skill branch-sync-and-push-safety --agent codex # Gemini CLI npx -y skills add kunchenguid/no-mistakes --skill branch-sync-and-push-safety --agent gemini # Windsurf npx -y skills add kunchenguid/no-mistakes --skill branch-sync-and-push-safety --agent windsurf # Cline npx -y skills add kunchenguid/no-mistakes --skill branch-sync-and-push-safety --agent cline ``` ## Qué hace - Nota interna sobre `internal/branchsync`: `sync`, `axi sync` y la acción `u` de la TUI comparten un servicio cuya única mutación normal del worktree es un movimiento guardado a un binding de push del pipeline recién verificado. - El estado pasivo nunca hace fetch y los estados bloqueados nunca hacen reset, stash, merge, rebase, force, switch, delete ni actualizan un remoto externo. - Cada operación de red tiene su propio contexto hijo acotado por `Service.RemoteTimeout` (ajuste global `branch_sync_remote_timeout`, 60s por defecto). - Un run TERMINAL con commits de pipeline sin publicar solo se recupera desde evidencia verificada y no conflictiva; `preservedContainsLocalWork` es una prueba ejecutable de merge-tree, nunca identidad de parche. - El objetivo del tool es no perder código: ante la duda, rechazar el push y mostrar un finding antes que cualquier recuperación ingeniosa; todo force-push pasa por `resolveForcePushDecision`. ## Cuándo usarla - Se cambia la sincronización de la rama local, la recuperación de custodia, el binding del head tras el review, el rebase o la seguridad del force-push. ## Qué la activa - "Voy a tocar la lógica de sincronización de rama en no-mistakes" - "Cambia el timeout de las operaciones de red de branch-sync" - "Revisa la seguridad del force-push tras un rebase a mitad de run" ## Archivos - SKILL.md — 10 KB ## SKILL.md Reproducido tal cual desde kunchenguid/no-mistakes bajo MIT. Esta sección es el documento original y está en inglés. **Guarded Local Branch Synchronization (`internal/branchsync`)** - `sync`, `axi sync`, and the TUI `u` action share one service whose only ordinary worktree mutation is a clean guarded move to an exact freshly verified pipeline push binding: strict fast-forward for behind branches, or an anchored reset to an equivalent diverged pipeline head when local unique work is already represented there. Under `--recover`, the worktree can only strict-fast-forward to the gate-preserved head, or adopt a diverged preserved head that `preservedContainsLocalWork` proves carries every local change. Passive status never fetches, and blocked states never reset, stash, merge, rebase, force, switch, delete, or update an external remote. - Give each network remote operation its own bounded child context derived from the caller: `Refresh` must not share one deadline across sequential `git.LsRemote` and `git.FetchRemoteBranchToPrivateRef` calls, and `Apply` uses the same per-operation budget for its final live check. The per-operation budget is `Service.RemoteTimeout`, sourced only from the operator's global `branch_sync_remote_timeout` setting (default `config.DefaultBranchSyncRemoteTimeout`, 60s); `RepoConfig` deliberately has no matching field. `Recover`'s local-gate fetch is outside this network deadline contract. Regressions: `TestRefreshSlowSuccessfulLsRemoteDoesNotStealFetchBudget`, `TestRefreshSlowButSuccessfulLsRemoteAloneExceedsItsOwnBudgetReportsOffline`, `TestRefreshRaisedRemoteTimeoutAcceptsTheSameLegitimateSlowLsRemote`, `TestRefreshParentCancellationStopsFetchAfterLsRemoteSucceeds`, `TestServiceRemoteTimeoutDefaultsToConfigDefault`, `TestLoadGlobal_InvalidBranchSyncRemoteTimeout`, `TestLoadRepo_BranchSyncRemoteTimeoutIsNotARepoSetting`. - Successful pipeline pushes persist the exact SHA, credential-free target fingerprint/ref, and generation; legacy rows remain nullable and must never infer provenance from mutable `head_sha`. Structured PR lifecycle retires merged/closed branches. The service rechecks the invoking worktree, target, live remote equality, ancestry or equivalent-divergence proof, generation, and all mutable assumptions immediately before apply. - A TERMINAL run with unpublished pipeline commits (moved head) is recoverable only from verified, non-conflicting evidence: inspection and `Recover` share one eligibility model. Equal/ahead local ancestry can create the local anchor without requiring gate access, but available gate evidence must agree; importing a missing preserved head requires exact or safely anchorable gate evidence, a clean worktree, and either ancestry or the content-preservation proof below. Only then does inspection report `blocked_pipeline_owned_recoverable` + `next_action recover_custody` with the exact submitted/current-head and relation facts (active runs keep the plain block). Missing, non-commit, symbolic, or conflicting evidence, and import cases that are dirty or genuinely divergent, fail closed with manual reconciliation instead. `sync --recover` anchors the preserved head at `refs/no-mistakes/recover/` before stamping `runs.custody_returned_at`. Cancellation RELEASES a terminal run that never changed the submitted head (`head_sha == submitted_head_sha`, no push, no custody stamp): selection keeps it visible so it never misreports as `blocked_wrong_branch`, and it classifies `user_owned` - no `next_action`, non-blocking exit, never represented as recoverable custody, `--recover` there is an idempotent no-op that mutates nothing, and a fresh `axi run` or separately authorized direct push is never blocked. Equal/ahead worktrees anchor locally without requiring gate access, but an available gate's existing recovery ref must agree with the recorded head; behind/diverged worktrees verify and fetch the preserved head from the run-specific recovery ref, fast-forwarding only a clean behind worktree. A cancelled validation routinely leaves a preserved head that is a REBASE of the local branch, which equality and ancestry read as plain divergence, so a clean diverged worktree is adopted when `preservedContainsLocalWork` proves containment. That proof is an executable `merge-tree` three-way merge whose result must equal the preserved head's tree, anchored on the merge-base - never `runs.base_sha`, the previous gate head. It deliberately does NOT use patch identity: patch IDs discard hunk locations and whitespace, so they cannot tell a genuine replay from a same-shaped edit to another identical block, and a containment claim built on them is not a proof. Everything undecidable escalates, including a rebase whose fix rounds also rewrote operator lines, where nothing separates a deliberate fix from a dropped change. Adoption anchors the pre-recovery local head at `refs/no-mistakes/recover-local/`, then moves the branch with Git operations that fail closed on their own rather than after an observation - an atomic `update-ref` CAS plus `read-tree -m -u`, never check-then-act followed by `reset --hard`, which destroys anything landing in the gap. `recoverAdoptPreserved` owns the reasoning. Terminalization pins every verified unpublished head at `refs/no-mistakes/recover/` before the managed worktree can be removed. Recovery reads that run-specific ref rather than requiring the gate branch to match, so aborts, rebases, and pre-push failures remain recoverable while an independently moved gate branch is preserved. Legacy recorded heads that still exist as dangling gate objects are anchored on recovery; a truly missing recorded head reports a distinct manual-reconciliation action instead of advertising an impossible `recover_custody` command. When the operator keeps a behind or diverged local head instead of taking the preserved head, `--keep-local` never touches the worktree and CAS-moves the gate branch to the kept head, staging objects via gate-side fetch - never a push, which would fire the receive hook and start a run. The full relation matrix and fail-safe rules live in the `Recover` doc comment in `internal/branchsync/sync.go`. - Public guidance is owned by `internal/skill/skill.go` plus live AXI strings, then regenerated with `make skill`. Core regressions live in `internal/branchsync` (incl. `recover_test.go`), `internal/cli/sync_test.go`, `internal/tui/branch_sync_test.go`, and e2e `TestAxiBranchSyncJourney` / `TestAxiCustodyRecoveryJourney` / `TestAxiCustodyRecoveryAfterRebaseJourney` / `TestAxiPrePushAbortUnmovedHeadCustodyJourney`. **Post-Review Head Continuity and Push Binding** - Every step after Review in the fixed pipeline order (Test, Document, Lint, Push, PR, CI) calls `assertPipelineHeadContinuity` at entry. The helper is the single semantic owner: equal or descendant live heads continue; backward, sibling, and unverifiable heads fail before the step performs work. Regression: `TestPostReviewStepsRefuseHeadClobberAtEntry`. - A successfully completed full review atomically records `runs.review_approved_head_sha`; parked, failed, skipped, and legacy reviews carry no inferred authority. Push reads that durable binding, permits only the exact commit or a descendant, and pushes the verified immutable SHA rather than mutable `HEAD`. Never infer approval from `runs.head_sha`, a worktree, gate ref, or remote branch. Regressions: `TestPushStep_RefusesPostReviewClobberWithoutLaterPipelineCommit`, `TestPushStep_BindsRemoteAndDatabaseToVerifiedCommitWhenHEADMovesDuringPush`, `TestExecutor_FullRereviewReplacesApprovalWithoutAuthorizingParkedRound`. **Rebase Base & Force-Push Safety (data-loss prevention)** - The whole job of this tool is to not lose people's code; favor refusing the push and surfacing a finding over any clever recovery. The comments in `internal/pipeline/steps/forcepush.go` own the full reasoning; the invariants are the next three bullets. - Rebase bases come from the freshly fetched authoritative remote refs, never local or stale state; and a branch built on unpushed local-default-branch commits parks with `NeedsApproval` + `AutoFixable=false` instead of silently widening the PR (`detectBundledLocalDefaultCommits`, #283). - Every force-push routes through `resolveForcePushDecision`, which re-reads the live remote head and allows the push only for a new branch, an already-equal remote, an unchanged `lastSeenSHA`, or remote commits already incorporated by patch-id (excluding `^baseSHA` history the run knowingly rewrites). Anything else refuses, and a failed ls-remote/fetch fails closed; never degrade to a bare `--force`/`--force-with-lease` without an explicit anchor. - `lastSeenSHA` must stay the head the run last **observed** (from run/prior-run push provenance or the remote-tracking ref), never the live remote tip: the rebase step refreshes `origin/` only on a normal push, NOT on a force push. CI repairs commit locally and restart validation at Review; the later Push step owns their remote update and force-push safety. Anchoring a lease to a SHA read immediately before pushing is the original #281 bug (it always passes and protects nothing); always-fetching the branch on force push recreates it. Never reintroduce either. - Regressions: `TestPushStep_RefusesToClobberAdvancedUpstreamBranch` (#305), `TestForcePushRun_RefusesToClobberOutOfBandBranchCommit`, `TestRebaseStep_DetectsUnpushedLocalDefaultBranchCommits` (#283), `TestResolveForcePushDecision_*`, `TestExecutor_CIRestartRevalidatesBeforePush`, `TestPushStep_AllowsForcePushAfterMidRunRebaseOverPriorPushedGeneration` (#837), `TestPushStep_AllowsForcePushOnRerunOverPriorRunPushedGeneration` (#837). ## Dónde encaja - Categoría: [Herramientas para desarrolladores](https://skillsagentes.com/categorias/herramientas-desarrollo.md) — Skills que cambian cómo tu agente escribe, revisa y despliega código. - Creador: [kunchenguid](https://skillsagentes.com/creators/kunchenguid.md) — 16 skills en el directorio - [Todas las skills](https://skillsagentes.com/skills.md) - [Ranking de instalaciones](https://skillsagentes.com/ranking.md) ## Otras skills del mismo repositorio - [No Mistakes](https://skillsagentes.com/skills/kunchenguid/no-mistakes/no-mistakes.md): Valida tus cambios de código por el pipeline de no-mistakes (review de código automatizado, tests, lint, docs, push, PR y CI) antes de que lleguen al destino de push configurado. Se activa con `/no-mistakes`. - [Testing Conventions](https://skillsagentes.com/skills/kunchenguid/no-mistakes/testing-conventions.md): Nota interna del proyecto no-mistakes. Se usa al añadir o cambiar tests, el harness e2e, el aislamiento de procesos de test o el sharding de tests en CI. - [Pr Publication Safety](https://skillsagentes.com/skills/kunchenguid/no-mistakes/pr-publication-safety.md): Nota interna de seguridad del proyecto no-mistakes. Se usa al cambiar el render del cuerpo del PR, la redacción de rutas de home, la publicación de rutas de artefacto o los marcadores de attestation de pipeline. - [Ci Monitor](https://skillsagentes.com/skills/kunchenguid/no-mistakes/ci-monitor.md): Nota interna del proyecto no-mistakes. Se usa al cambiar la readiness de CI, la recogida de checks del forge, los reruns, los timeouts de CI o la monitorización del ciclo de vida del PR. - [Pipeline Review And Agents](https://skillsagentes.com/skills/kunchenguid/no-mistakes/pipeline-review-and-agents.md): Nota interna del proyecto no-mistakes. Se usa al cambiar las sesiones de review, las decisiones sobre findings, los timeouts de agente, el comportamiento del Test local o la conformidad con la intención. ## Skills relacionadas - [Finishing A Development Branch](https://skillsagentes.com/skills/obra/superpowers/finishing-a-development-branch.md): Úsalo cuando la implementación esté completa, todos los tests pasen, y necesites decidir cómo integrar el trabajo. - [Writing Skills](https://skillsagentes.com/skills/obra/superpowers/writing-skills.md): Úsala al crear nuevas skills, editar skills existentes o verificar que funcionan antes de desplegarlas. - [Domain Modeling](https://skillsagentes.com/skills/mattpocock/skills/domain-modeling.md): Construye y afila el modelo de dominio de un proyecto. Úsalo para fijar la terminología o un lenguaje ubicuo, registrar una decisión arquitectónica, o cuando otro skill necesita mantener el modelo. - [Setup Pre Commit](https://skillsagentes.com/skills/mattpocock/skills/setup-pre-commit.md): Configura hooks de pre-commit con Husky y lint-staged (Prettier), typecheck y tests en el repo actual. Úsalo para añadir hooks de pre-commit, configurar Husky o lint-staged. - [Setup Ts Deep Modules](https://skillsagentes.com/skills/mattpocock/skills/setup-ts-deep-modules.md): Conecta dependency-cruiser a un repo TypeScript para que cada paquete sea un módulo profundo: implementación oculta en subcarpetas, alcanzable solo a través de sus entry points. --- Skills Agentes · [Índice de páginas en markdown](https://skillsagentes.com/sitemap.md) · [Inicio](https://skillsagentes.com/index.md)