Skip to content

v0.5.1 — identity hardening + dev environment

Choose a tag to compare

@siaginw siaginw released this 04 Sep 19:18
· 5 commits to main since this release

SheetDiff v0.5.1 — identity hardening + a real dev environment

Two passes in one release: a fresh adversarial audit of v0.5's smart-identifier hierarchy (five real defects found and fixed), and a researched dev-environment overhaul based on how comparable open-source Next.js projects (cal.com, dub, formbricks, documenso, vitest, drizzle-orm) actually work in 2026.

Fixed — the audit pass

  • Identity is now resolved once, on latest data, for every slice. The auto-detected key column was being re-detected per snapshot; when uniqueness flipped between them (two rows share a date on a baseline), the same row keyed differently over time and a compilation tab's baseline escaped ownership — deflating placed-since, the exact bug class v0.5 claimed to have killed.
  • Dates no longer masquerade as row identifiers. A unique Date column used to outrank a real ID/SKU column in detection scoring (making a date correction look like remove+add), and the dedup's auto-tier keyed by date — two crew logs spanning the same period collapsed into one tab and vanished from billing. Date/week now score below real identifiers and are skipped by the dedup auto-tier entirely; a date key you pick deliberately is still honored.
  • sheetBillableNow honors the per-tab key column — the sheet-page badge and the money page can no longer disagree, the invariant that function exists to guarantee.
  • A mostly-copy tab that owns real work is no longer skipped wholesale — the coverage-based compilation classification now caps strays at 2% of keyed rows (the real Line List sits at 1.9% and still classifies; 20-copies-plus-straggler no longer vanishes).
  • Removals net out per tab again — the slice walk's key-namespace exception was inverted (within-tab repeats dropped, cross-tab repeats kept).

New — the dev environment

  • Prettier with Tailwind class sorting and import organizing; the repo is formatted once and npm run format / format:check keep it that way.
  • Pre-commit hooks (husky + lint-staged): ESLint --fix + Prettier on staged files only, skipped in CI.
  • Coverage with teeth: vitest v8 coverage with enforced thresholds (currently ~80% lines), run in CI.
  • npm run verify: format + lint + typecheck + tests in one command — what CI checks, what you run before pushing.
  • Security workflows: CodeQL (weekly + PRs) and zizmor (lints our own Actions files).
  • Hardened CI: least-privilege permissions, cancel-in-progress, timeouts, persist-credentials: false, format + coverage steps.
  • Repo hygiene: .nvmrc, .editorconfig, .vscode settings + recommended extensions, PR template, feature-request form, FUNDING.
  • knip dead-code sweep — 6 unused scaffold components removed, and the phantom google-auth-library type import is now derived from googleapis itself.

367 tests green (6 new regression tests pin every audit fix). Node 22+.