kadence

Changelog

What shipped, release by release, with the reasoning that came with it.

[0.3.2] — 2026-09-09

Nothing in the package changed. src/, scripts/, package.json and the lockfile are identical to 0.3.1 — the diff across all four is empty — so the code you get is the code you already have, and there is no behavioural reason to take this one.

What changed is the pipeline that produces it. From here on the tarball is built in a job that does not execute dependency install scripts and that pins every action it runs to a commit rather than a tag.

Security

  • Dependency lifecycle scripts no longer run in CI or on release. npm ci passes --ignore-scripts in both workflows. A postinstall runs with the full rights of the job, which is the primary npm supply-chain vector. Exactly one dependency here declares one — esbuild — and in 0.28 the platform binary arrives through optionalDependencies, so the script has nothing left to do. Measured rather than assumed: clean install, 35 KB bundle, full suite green on Node 20 and 22.
  • Both workflows pin actions/checkout and actions/setup-node to commit SHAs, with the version in a trailing comment. A tag is mutable: @v4 is whatever its owner last moved it to, and it runs with the job's permissions.

Publishing is unaffected: --ignore-scripts governs installing dependencies, not this package's own lifecycle, so prepublishOnly still gates every release on typecheck, tests and build.

[0.3.1] — 2026-09-08

A patch, and the reason to take it is the fix: anyone already on 0.3.0 has a state cache that can serve records folded by the previous build. The added field is additive within kadence/v1, which the contract permits at any version.

Added

  • decision list and decision show now report who wrote the recordsource: "human" | "agent", from KADENCE_SOURCE at the time of writing. kadence has always refused to guess this when writing an event; that refusal only means something if the source survives to the point of reading. Human output marks only agent-written records, because labelling every human one in a repository written mostly by people hides the exception.

Fixed

  • The state cache could serve a shape folded by an older version of kadence. .kadence/state.json carries a version, and it was not bumped when a projected record gained a field — so after an upgrade the cache kept returning records without the new field, and any consumer branching on it saw undefined. Invariant I6 says deleting the cache changes nothing, which is true; what bites is keeping it. The version is now pinned to the projected shape by a test, so adding a field without invalidating the cache fails the build.

    Found by using the product on itself: three decisions recorded minutes earlier refused to show their source.

[0.3.0] — 2026-09-08

The journal held what happened. It now holds why — and the reasoning cannot quietly go stale, because superseding a decision is one event rather than two edits somebody has to remember to make. Reasoning in ADR-010; the guide is Recording why.

Added

  • kadence decision — why a choice was made, as an event next to the work. --why is required; without it the record is a changelog line. --supersedes writes a single record and the backward link is derived while folding, so the two directions cannot fall out of step — the failure that makes a reversed decision keep looking authoritative in file-based tools. decision list returns what is still in force; --all adds the history.

    Numbers are derived, so two branches can each record a decision and merge without a conflict or a renumber. Both are covered by integration tests on real git branches.

  • Documents linked to workkadence task doc KAD-1 docs/design.md, and --doc on a decision. kadence does not store the document: it stays plain markdown and git keeps versioning it. What git cannot say is that this file explains this task, and that is the only thing recorded. A missing file is a warning, not a refusal — it may arrive in a later commit.

    Measured before building (Probe D): across five real questions, grep finds the answering document every time and buries it among 10–35 candidates.

  • task show --json now carries decisions and docs; both are always arrays, so an agent never has to branch on their absence.

    A decision that supersedes another inherits the task it was about, unless you name a different one. Without that, superseding quietly stripped a task of its reasoning — the old decision dropped out of task show and the replacement had never been attached. Found by installing the package and using it, with 538 tests green.

  • The files init writes into your repository now say what produced them: <!-- generated by kadence X.Y.Z — refresh with kadence init -->. A context file with no marker rots silently — a year on, nobody knows whether the section is current or what put it there, and we write into other people's repositories. Deliberately no date: it would rewrite the file on every new day and fill diffs with noise, while the version changes exactly when the content might have.

[0.2.2] — 2026-09-08

Two promises from 0.2.1 that the code did not keep, found by reading the published package rather than the source.

Fixed

  • Most --json failures carried no error.code. ADR-009 says every failure has one; thirty-seven paths returned a bare sentence — most of sprint, all of template, board config, and every "unknown action". An AI agent could tell that something failed and nothing else. The existing tests compared the published code list against the constant, so they could not see that the commands were not using it; a new test now provokes twenty-seven real failures and requires a code from the list on each.
  • unknown_status hinted at a command that does not exist. It named kadence board statuses --json; following it produced a second failure, which itself had no code. The hint is now kadence board config --json, which already returns the configured columns, and every hint the CLI can emit is executed by a test that requires it to succeed.
  • cac was a runtime dependency that nothing loaded. esbuild bundles it, so the only external import in the published output is blessed — every install downloaded 52 KB for nothing. Moved to devDependencies, with a test that compares what the manifest declares against what the build actually imports.

Added

  • Two error codes, additive within kadence/v1: template_not_found, and conflicting_state for arguments that are understood but refused by the current state — a closed sprint, one already started, one still open at close.
  • received and allowed on the failures where they are knowable, including the action lists behind "unknown action".

[0.2.1] — 2026-09-08

Why 0.2.1 and not 0.2.0

0.2.0 cannot be published under this name. A different package called kadence used that version on 2026-02-05 — before this one claimed the name — and npm never allows a version number to be reused, not after an unpublish and not by a new owner. Nothing was released as 0.2.0; this is the first release of the 0.2 line.

The agent contract, made real. schema: "kadence/v1" used to be a version string that nothing checked; now the contract is published, the failures are machine-readable, and the responses can be narrowed to what an AI agent actually reads. Reasoning in ADR-009, measurements in Probe C.

Added

  • kadence schema --json — the machine-readable contract behind schema: "kadence/v1": every command, the fields you can rely on, and every error code. It works outside a repository, because an AI agent asks what the tool does before it has a project to ask about.
  • Failed --json calls now carry error.code from a closed list, plus received, allowed and hint where each is knowable. allowed matters most for statuses: they are configured per project, so an agent cannot learn the valid set from documentation. There is deliberately no retryable field — with no network and no lock, the same input always fails the same way.
  • --fields on board --json and task list --json, so an agent can ask for the columns it reads instead of every description. On a 200-task board that is 130,799 bytes down to 11,015. An unknown name fails with unknown_field and the list of what exists.

Changed

  • init now writes the kadence section into CLAUDE.md as well as AGENTS.md. Claude Code does not read AGENTS.md, so a repository carrying only the latter was invisible to the largest agent audience — the promise that "the AI agent finds it on its own" was not true for them. Text a human wrote in either file is left untouched, and a repeat init does not duplicate the section.

Fixed

  • Any --json response larger than the pipe buffer was truncated mid-string. process.exit() does not wait for an asynchronous write to drain, and writing to a pipe — how every agent reads us — is asynchronous, while writing to a file is not. A 200-task board produced 131,072 bytes and a parse error; the same command redirected to a file was valid. Output is now written synchronously.

Note on the roadmap

kadence context <task> will not be built. task show --json already returns the whole history of one piece of work in 948 bytes, and that number does not grow with the project — the only thing left to add was a format nobody has asked for.

[0.1.5] — 2026-09-03

Changed

  • README rewritten to lead with the number the product exists for — what a story point actually costs — instead of a feature list. Claims now carry their evidence inline: the merge thesis links to the 8,396-commit study and to the integration test that proves it, and the performance table says these are tests that fail the build.
  • Repository URLs follow the rename to bogutskiandriy/kadence.

[0.1.4] — 2026-09-03

Fixed

  • The package depended on itself. kadence@^0.1.1 sat in dependencies, so every install pulled a second, older copy of the tool into node_modules and shipped it to users. Removed; the published tarball is now 32.7 kB with eight files in it.
  • @types/blessed moved to devDependencies. Type definitions are not needed at runtime, and every install was paying for them.

Repository

  • Developer tooling (.claude/, .serena/) is no longer committed: 381 files and 3.8 MB of it, against 94 files of actual product. What belongs in git and what does not is written down in ADR-007, and .gitignore now also covers .env, coverage output and editor leftovers.

[0.1.3] — 2026-09-03

Testing

  • End-to-end coverage through the real binary: a full sprint from init to sprint close with velocity computed from actual events, every reachable command checked for a clean exit, three branches editing one task, an agent driving the tool with JSON alone, and the events folder vanishing on a branch switch. 390 tests.

[0.1.2] — 2026-09-03

Documentation

  • The README opened with npx kadence init and said nothing more, so the obvious next step — kadence board — failed with "command not found". npx fetches a package for one command and leaves nothing installed. Global install is now the first instruction, with the npx path shown as the alternative it is.

[0.1.1] — 2026-09-03

Fixed

  • kadence --version reported 0.1.0-dev while the published package was 0.1.0. The CLI carried its own copy of the version string; it is now injected from package.json at build time, with a test that fails if the two ever diverge again.

[0.1.0] — 2026-09-03

First release. Tasks, sprints and velocity as plain files inside a git repository, with no server, account or network.

Core

  • Append-only event journal: one file per event, never rewritten. Two branches editing the same task merge without a conflict — verified on real git branches, not only in theory.
  • State folded from the journal on every read, so the board cannot drift from reality. A snapshot cache makes that cost 7 ms on 10,000 events.
  • ULID identifiers, so event order is a property of the id rather than of how far apart machine clocks have drifted.

Tasks

  • Title, description, type (task/bug/story/epic), priority, labels, assignee, due date, estimate, comments, logged time.
  • Subtasks and blocking dependencies, with cycle detection that reports a loop instead of rejecting the later edit — rejecting it would make the state depend on merge order.
  • Search across titles, descriptions and comments; filters, sorting, and bulk operations that apply all-or-nothing.
  • Templates for repeated task shapes.

Sprints

  • Plan the next sprint while the current one runs.
  • Velocity and hours-per-point derived from events, so the numbers cannot be forgotten or faked.
  • Burndown reconstructed from the journal for any day — including days before the feature existed.

Board

  • kadence board — plain columns for pipes and scripts.
  • kadence ui — interactive kanban: keyboard, mouse, drag between columns, and every field editable in place. Loads lazily, so kadence task add never pays for it.
  • Custom columns per team; done cannot be removed because every analytic is computed from it.

For agents

  • --json on every command with a stable schema: "kadence/v1".
  • stdout carries JSON only; warnings go to stderr.
  • init writes a guide the agent finds on its own.

Known limits

  • The velocity bet is not yet validated with users. See README, Honest status.
  • Terminal interaction is covered by manual testing; only the key router is unit-tested.

The canonical file lives in the product repository: CHANGELOG.md.

On this page