PTENES
5.3 Track 5 ~45 min

📦 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

PATCH 1.2.1 bugfix — no breaking change MINOR 1.3.0 new feature — compatible MAJOR 2.0.0 breaking change

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.

git commands for version control
# 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.md — recommended format
# 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

1

Bad recent commit — git revert

Creates a new commit that undoes the changes. History is preserved. Safe for shared branches.

git revert HEAD~1
2

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
3

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.

safe refactoring workflow
# 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.

tests/aggregate.test.ts — Vitest example
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"
TODOs with context — recommended format
// 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

✅ You learned
  • • 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
🚀 Next Steps
  • • Configure semver in your project
  • • Create the initial CHANGELOG.md
  • • Add Vitest to the project
  • • Audit the existing TODOs