📦 Maintenance, versioning, and CHANGELOG
Semver, a structured CHANGELOG, safe rollback, confident refactoring, and how to manage technical debt in projects that run for months.
1 🏷️ Semver — versions that communicate intent
Each semver number communicates the impact of the change
Semantic Versioning (semver) isn't bureaucracy — it's communication. Each number has a precise meaning that lets anyone (and Claude) understand the impact of an update.
# Criar tag de versão
git tag -a v1.2.3 -m "Release 1.2.3 — Documents Gallery"
# Listar tags
git tag --list
# Push tags para remote
git push origin --tags
# Ver diff entre versões
git diff v1.2.0..v1.3.0
# Voltar para versão específica (checkout)
git checkout v1.2.0 -- src/components/Gallery.tsx
PATCH x.y.Z
Bugfix. API unchanged. Safe to update without reading the changelog.
MINOR x.Y.z
New feature. Backward-compatible. Read the changelog for what's new.
MAJOR X.y.z
Breaking change. May break existing code. Read the migration guide.
2 📋 Well-structured CHANGELOG
The CHANGELOG is the project's diary. It follows the "Keep a Changelog" format—organized by version with Added, Changed, Fixed, and Removed sections.
# Changelog
## [Unreleased]
### Added
- Suporte a dark mode no painel principal
## [2.3.0] — 2026-05-31
### Added
- Documents Gallery: visualização de docs Obsidian no dashboard
- Filtro por vault na sidebar
### Changed
- Script aggregate.ts agora processa docs em paralelo (3x mais rápido)
### Fixed
- Bug em live-data.json quando Pinecone retorna 0 resultados
## [2.2.0] — 2026-04-15
### Added
- Skill /personas: panteão de personas YAML locais
- Painel de personas no dashboard
### Changed
- Deploy migrado de Vercel para Cloudflare Pages
## [2.1.0] — 2026-03-01
### Added
- Skill /dream: auditoria de 24h em 8 buckets de sinal
✓ Effective CHANGELOG
- • One entry per version, with a date
- • Semantic sections (Added/Changed/Fixed)
- • [Unreleased] section for the next version
- • Short phrases focused on impact
- • Updated with every merged PR
✗ Useless CHANGELOG
- • "Several bugs fixed"
- • No dates or versions
- • Last entry is 6 months old
- • Copying and pasting commit messages
- • Mixing breaking changes and bug fixes
Claude as a CHANGELOG assistant
At the end of a productive session: "Baseado nas mudanças que fizemos, adicione entradas na seção [Unreleased] do CHANGELOG.md seguindo o formato Keep a Changelog."
3 ⏪ Safe rollback
With Claude generating code quickly, errors happen. Knowing how to roll back without drama is the most underrated skill in long-term projects.
Rollback strategies by scenario
Bad recent commit — git revert
Creates a new commit that undoes the changes. History is preserved. Safe for shared branches.
git revert HEAD~1
Specific corrupted file — git checkout
Restores a file to the version from a previous commit without affecting anything else.
git checkout v2.2.0 -- src/components/Gallery.tsx
Deployment rolled back — previous version in production
In Cloudflare: dashboard → Deployments → select a previous version → "Rollback". Instant, with no code.
✓ Prepared for rollback
- • Version tags for each release
- • Small, atomic commits
- • Feature flags for new features
- • Automated deploy (not manual)
- • Tests that catch regressions
✗ Impossible rollback
- • No tags — you don't know which version to roll back to
- • Huge commits with 50 files
- • Database migrations without a downgrade
- • Manual deploy with no history
- • No tests to detect breakage
4 🔧 Refactor Safely
Refactoring with Claude is fast — and that’s why it’s dangerous. Without tests, you don’t know whether the "cleanup" broke something. The ritual: tests first, refactoring next.
# 1. Garantir que testes passam ANTES de refatorar
bun test
# 2. Criar branch para a refatoração
git checkout -b refactor/aggregate-pipeline
# 3. Refatorar em passos pequenos, testar após cada passo
bun test --watch
# 4. Commit atômico por mudança semântica
git add src/lib/aggregate.ts
git commit -m "refactor: extract parseObsidianVault to separate function"
# 5. Confirmar que tudo ainda passa
bun test
# 6. Merge via PR (revisão antes de merge)
git push origin refactor/aggregate-pipeline
Safe refactoring prompt
Tell Claude: "Antes de refatorar, mostre quais testes cobrem este código. Depois refatore em passos pequenos e execute os testes após cada passo."
✓ Safe refactoring
- • Tests passing before you start
- • Dedicated branch
- • Small steps with commits
- • Run tests after each step
- • PR for final review
✗ Risky refactoring
- • Refactor directly on main
- • Change 10 files in the same commit
- • No tests to validate behavior
- • Run tests only at the end
- • "Claude said it's correct"
5 🧪 Tests as living documentation
Well-written tests are the most reliable spec: they have to pass to exist. Unlike comments and README files, they don’t silently become outdated.
import { describe, it, expect } from 'vitest'
import { parseObsidianVault } from '../src/lib/aggregate'
describe('parseObsidianVault', () => {
it('retorna array vazio quando vault não existe', async () => {
const result = await parseObsidianVault('/nonexistent/path')
expect(result).toEqual([])
})
it('extrai notas com frontmatter válido', async () => {
const result = await parseObsidianVault('./fixtures/vault')
expect(result.length).toBeGreaterThan(0)
expect(result[0]).toHaveProperty('title')
expect(result[0]).toHaveProperty('tags')
})
it('ignora arquivos sem extensão .md', async () => {
const result = await parseObsidianVault('./fixtures/vault')
result.forEach(note => {
expect(note.path).toMatch(/\.md$/)
})
})
})
Project-specific testing strategy
Unit tests
Pure functions, parsers, transformations. Fast, no I/O. 80% coverage.
Integration tests
Modules working together. Scripts with fixtures. 15% coverage.
E2E tests
Complete critical workflows. Slow; run in CI. 5%, but the most important ones.
6 💳 Controlled technical debt
Technical debt isn't always bad — sometimes it's the right decision at the time. The problem is when it accumulates without being tracked. With Claude, debt accumulates much faster than usual.
✓ Tracked debt
- • TODO/FIXME with context and date
- • GitHub issue for each piece of technical debt
- • Monthly cleanup sprint
- • TODO count metric in CI
- • Explicit decision to “pay later”
✗ Invisible debt
- • TODO without an author or date
- • Duplicated code “for now”
- • any types scattered throughout the TS
- • Outdated dependencies ignored
- • "We'll refactor later"
// TODO(nei, 2026-05-15): Este parser é O(n²) para vaults grandes.
// Aceitável para agora (<500 notas) mas precisa de índice quando
// o projeto escalar. Ver ADR-003 para contexto da decisão.
// Issue: github.com/user/project/issues/42
function parseAllNotes(vault: string) {
// ...implementação atual...
}
Debt audit with Claude
Monthly: "Liste todos os TODO/FIXME do projeto com contexto e estime o impacto de cada um. Priorize por risco × esforço."
📋 Module summary
- • Semver: MAJOR.MINOR.PATCH with semantics
- • CHANGELOG in Keep a Changelog format
- • Rollback strategies for each scenario
- • Refactoring in steps with tests
- • Tests as living documentation
- • Technical debt tracking
- • Configure semver in your project
- • Create the initial CHANGELOG.md
- • Add Vitest to the project
- • Audit the existing TODOs