• v2.3.0 24b723f5c6

    v2.3.0 — where the bytes live
    All checks were successful
    test / node-test (22) (push) Successful in 49s
    test / node-test (24) (push) Successful in 50s
    test / self-verify (push) Successful in 13s
    test / typecheck (push) Successful in 17s
    Stable

    john released this 2026-08-05 17:35:11 +00:00 | 1213 commits to main since this release

    Signed by john
    GPG key ID: 693AB15F91734B0C

    A context-efficiency cycle, grounded in a burnrate measurement: ~108.5k resident context per assistant turn against 565 tokens of output, with cache reads alone at 62.7% of spend. When cost is context multiplied by turns, carrying less is where the money is.

    Transport-only by default. It moves bytes and changes when they load, and removes no review, gate, rung or guardrail.

    Subagent output leaves the parent context

    cad-executor writes its report to .planning/phases/<N>/reports/plan-<k>.md and returns a five-field digest, so a PLAN PARTIAL or timeout continuation is rebuilt from the file and cannot re-run a task already listed complete. cad-verifier writes one findings file under a narrow Write grant, with Edit and MultiEdit still denied on all four rungs, and /cad-verify --deep pipes it straight into uat merge with no hand-transcription left. Reviewers receive refs valid in their own working tree, or --payload <file>, rather than an inlined diff.

    References load where they are used

    references/git.md is split into git-guard.md (rails 1, 2, 4) and git-publish.md (rail 3), so the four skills that only need the guard stop loading publish policy. The review triage gate moves into references/triage-gate.md, and its adjudicated arm is now an AskUserQuestion multi-select you tap rather than a paragraph asking you to answer in prose. All 17 conventions.md parentheticals are inlined at their use sites, leaving that file @-included nowhere in the plugin.

    One behavior fix rode along: the git.auto_close carve-out that suppresses the triage prompt was sitting in the generic adjudicated arm, so opting into the unattended land close suppressed it at every adjudicated gate, including ones where nothing was left to halt on the discarded findings. It is now scoped to pre_ship inside /cad-land.

    The always-on surfaces, and the ratchet that watches them

    23 skill and 19 agent description: lines are cut to one routing line each, 8,550 bytes down to 5,397, with zero trigger words dropped and nine gained. Those bytes ride the system prompt of every session in every project, whether or not you ever run a Cadence command.

    cadence-core/references/** and templates/** come under the weight budget as 23 exact-byte entries. That needed the measurement fixed first: both directory walkers wrapped one recursive readdirSync, so a single unreadable descendant returned nothing for the whole subtree, and self-verify named a directory that read fine with the errno of a different failure. Both now recurse per entry. A symlinked directory met during a walk is no longer descended, which makes a long-standing claim in the module header true for the first time.

    Measured

    Before After
    Twelve commands, turn-one load 231,422 B 199,687 B
    /cad-pause 18,523 B 8,197 B
    /cad-land 36,235 B 31,016 B
    Always-on descriptions 8,550 B 5,397 B

    Stated rather than netted away: the plugin's own weighed total went up over the same stretch, because moving a rule out of a shared reference and into the workflow that uses it puts those bytes on a measured surface for the first time. The win is in what a turn loads, not in what the repository weighs. And five of the twelve commands ended up slightly heavier, because their workflow files grew when guidance moved inline, which a forty-byte description cut was never going to pay for.

    Gates

    11/11 requirements traced, 20/20 acceptance criteria covered, 1156 tests passing, self-verify clean across 16 checks, tsc exit 0, budgets exact across all 92 weighed surfaces.

    Full detail in CHANGELOG.md.

    Downloads
  • v2.2.0 0bf62847dd

    V2.2.0
    All checks were successful
    test / node-test (22) (push) Successful in 54s
    test / node-test (24) (push) Successful in 55s
    test / self-verify (push) Successful in 15s
    test / typecheck (push) Successful in 19s
    Stable

    john released this 2026-08-04 18:17:09 +00:00 | 1272 commits to main since this release

    Signed by john
    GPG key ID: 693AB15F91734B0C
    Downloads
  • v1.5.0 a1453c3ab9

    v1.5.0 Stable

    crenshawdev released this 2026-07-28 20:21:47 +00:00 | 1381 commits to main since this release

    Signed by john
    GPG key ID: 693AB15F91734B0C

    Four corrections to things Cadence said about itself, and one structural
    change so there are fewer places left to say them.

    Added

    • Self-verify asserts every preloaded agent contract resolves. A skills:
      entry naming a skill that does not exist is skipped by the host silently,
      with only a debug-log warning, which leaves an agent running with no contract
      at all - a failure that reads as an agent ignoring its instructions rather
      than as a typo. The new agent-skills check fails loudly instead, and also
      flags a resolved skill that sets disable-model-invocation: true, which
      cannot be preloaded and produces the same end state by a different route.
      The tools lint now scans preloaded contracts as agent prose, so moving the
      contracts out of the agent bodies did not silently empty its input.

    Changed

    • Each agent's contract is stored once, as a skill preloaded through the
      skills: frontmatter field.
      The seven files in agents/ are now
      frontmatter plus a pointer, between 464 and 592 bytes each, down from as
      much as 8786. Six contract skills hold the prose, one per role rather than
      per file: cad-plan-checker and cad-plan-checker-high share one, which is
      what that pair always claimed to be. They carry user-invocable: false, so
      they never appear in the slash-command menu. Behaviour is unchanged; five of
      the six moved byte-identical. The exception is the plan-checker pair, whose
      high variant carried real behaviour of its own - shipping behaviour in a file
      whose only job is to name a rung is the failure this design exists to
      prevent, so it moved into the shared contract as a <rung> section and both
      files now state only which rung they are.
    • cad-plan-checker-high no longer reads another agent file at runtime.
      The @-include workaround is retired. The file itself stays, because it
      exists to carry effort: high - frozen in frontmatter, and named by string
      in route-table.json's escalate_effort_variant - and retiring it needs a
      rung ladder that does not exist yet.

    Fixed

    • The worktree fork point is selectable, and v1.4.0 said it was not.
      seams.md called it host-owned and NOT caller-controllable, and five other
      surfaces restated that binding on the strength of it. The host's
      worktree.baseRef setting decides it: fresh (the default) forks from the
      remote default branch, head forks from the local HEAD and carries the
      integration branch's unpushed work - which is the documented use case for
      isolating subagents on in-progress work. The fresh default is the whole
      cause of the phase-4 failure the false claim was written to explain. Every
      surface now states the setting, the version it holds for (Claude Code

      = 2.1.208), and the nuance that inside a worktree head is that
      worktree's own HEAD.

    • /cad-execute no longer parallelizes into worktrees that lack its plans.
      choose_path runs a new read-only seam, cadence-core/bin/worktree-base.mjs,
      which resolves the effective worktree.baseRef through the Claude Code
      settings cascade; under fresh, unset, or an unreadable answer the phase
      runs sequentially and names the fix. /cad-config offers to set "head" in
      the project's or the user's settings file - offers, and never writes a
      user's settings without being told to. The executor's <worktree_mode>
      assertion stays either way: a setting the user can change back, and a
      session CLI override no script can see, are not guarantees.
    • Per-trigger effort no longer claims to apply where it cannot reach.
      fire(trigger) resolved {gate, tier, effort} and consumed effort on the
      cross-model arm only. The claude-subagent arm dispatches through a seam
      whose surface is (agent_name, prompt, model?), so on a stock install the
      configured value was read, resolved, and dropped with nothing said - every
      trigger, every fire. Wiring it through is not available: effort is a
      subagent definition field with no per-dispatch override on the Agent/Task
      path, so varying it needs per-rung agent files. The key is scoped instead.
      review-triggers.md states which fields reach which backend,
      config.schema.json says it at the point of setting, and a fire whose
      configured effort differs from cad-reviewer's frontmatter-pinned high
      now names the difference in one line rather than silently ignoring it.
    Downloads
  • v1.4.1 465bb26d4b

    v1.4.1 Stable

    crenshawdev released this 2026-07-28 18:04:37 +00:00 | 1402 commits to main since this release

    Signed by john
    GPG key ID: 693AB15F91734B0C

    Two internally-inconsistent contracts, both closed by subtraction.

    cad-executor's terminal success-criteria check is gone (#65). Its <process> block required the check; its <report> block had no field to put the answer in, and execute.md never asked for it. goal_check already redoes that assessment one step later with the full phase diff in view and a stated purpose. Deleted rather than wired, because the consumer that would have justified it already exists. The per-task predict-then-verify at process step 2 is untouched.

    conventions.md states its real reach (#67). The file opened with "Shared rules every skill and workflow follows" while being @-included by exactly one skill and named in prose by 18 other files, so its rules reached a model only when something happened to read it. The header now says what is true: an on-demand reference, cited by path where a rule applies or @-included where a workflow needs the whole set, and nothing in it reaches an agent that has not read it. Including it everywhere was the rejected alternative, since it would spend resident context in every session on rules most invocations never need.

    Full changelog: https://github.com/crenshawdev/cadence/blob/main/CHANGELOG.md

    Downloads
  • v1.4.0 fba5879871

    Cadence 1.4.0 Stable

    crenshawdev released this 2026-07-28 16:47:20 +00:00 | 1406 commits to main since this release

    Cadence parsed four formats it owns with regexes that accreted a case at a
    time, and every one of them failed silently in both directions. An over-read
    invented a requirement id that came back later as an /cad-audit orphan. An
    under-read dropped a real path and handed the parallel-safety gate a false
    overlaps: [], so the gate dispatched two plans that both write
    src/shared.rs onto the same file. Both of those look exactly like success
    from the outside, which is the whole problem.

    I replaced those four readers with grammars I wrote down. Each one gets a
    reference file stating what it accepts, a table of the shapes it deliberately
    refuses and what it does with them instead, and a parser-level test per row.
    An input outside the grammar now earns a named diagnostic instead of quietly
    changing what the reader took.

    The plan-file frontmatter reader

    One normalized classifying pass replaces the accreted arms. The greedy
    \[(.*)\] is gone, so files: [a.md, b.md] # [see notes] reads two files
    instead of swallowing the comment's bracket, and requirements: # TODO above
    a block list reads the block instead of the comment. That second one was a
    regression I shipped in v1.3.1.

    Everything outside the grammar now reports on the audit and plan-overlap
    envelopes as frontmatter_issues. The shipped template's own former shape was
    one of the broken ones: a files: [] # comment key line with indented paths
    under it took the inline arm, so every path beneath it vanished with no
    diagnostic at all. Four more shapes earn names now: a quoted value with
    trailing text, a commented-out key line inside an open block, a missing space
    after the colon, a backslash escape, and a backtick-wrapped value.

    Paths reach plan-overlap byte-exact as the plan wrote them, so src/x(1) and
    lib/a`b.mjs survive unrewritten.

    One tokenizer for the git rails

    I closed the six rail-3 holes from the v1.3.1 known-gaps list, plus a seventh I
    found while gathering context. A quoted -C path with a space, & as a
    separator, $(...), backticks, a subshell, an escaped \", and the
    bash/sh/zsh/dash/eval wrapper set with -c all reached the network
    with no prompt before this. They ask now.

    Six more regex arms was the alternative, and regex patching is what produced
    the two push-rail regressions this repo already paid for, so I deleted the arms
    instead of extending them. One left-to-right pass in
    cadence-core/bin/lib/shell-tokens.mjs carries a single quote and escape
    state, keeps word boundaries, descends into substitutions and subshells, and
    re-tokenizes a wrapper's operands. Both rails read that one output, so they
    agree on what a wrapped command is.

    One deliberate regression comes with it. The guard detects a wrapper at any
    position, so it sees sudo bash -c "git push", but it only hard-refuses when
    both the wrapper and the git word sit at command position. Under
    git.on_protected: refuse that means sudo git commit and timeout 60 git commit now ask instead of hard-blocking. I dropped the enumerated prefix and
    shell-keyword sets that used to deny them: every prefix carries its own option
    grammar, three review rounds kept finding new members, and the enumeration
    falsely denied command -v git commit, which runs nothing. A missing deny
    costs a prompt on a real commit. A wrong deny blocks read-only work.

    The roadmap phase list

    An empty ## Phases derives a closed-milestone state now instead of
    unparseable-roadmap, so /cad-progress works in the window between a
    milestone close and the next cycle rather than calling the roadmap broken.
    status returns cycle: "none" as an additive field.

    A wiped checkbox list whose ### Phase N: detail sections survived is the
    signature of an interrupted prune, and it reports as one. A heuristic read that
    same tree as a cleanly closed milestone, which is why I reverted the first
    attempt at this during the v1.3.1 close.

    The ## Active requirement section

    An ## Active requirement no phase has picked up now breaks /cad-audit as
    unpicked. The gate used to hold only against a zero-row traceability table,
    so it went quiet as soon as one phase had a plan, which is the state a
    milestone spends most of its life in. That blind spot is how the v1.2.0 and
    v1.3.1 closes both got through without their audits firing.

    Two things to know before you upgrade. counts.total now counts traceability
    rows plus unpicked ids rather than rows.length, so anything you wrote against
    total === rows.length reads a different number. And unseeded moves the
    verdict now, reversing the additive shape I shipped one milestone earlier: a
    diagnostic that never moves the verdict leaves the ship gate exactly as
    permeable as it was. A project with no ## Active heading gains no break from
    any of this.

    The spine's own bookkeeping

    /cad-plan seeds its own traceability rows through a new seed-reqs
    subcommand, so a milestone close no longer needs a hand-populated table before
    /cad-audit passes. It needed one at the last two closes, and that is exactly
    why neither audit fired.

    A worktree executor now checks that its own PLAN-<k>.md exists before task 1
    and halts with a blocked checkpoint naming the missing path, rather than
    planning against a stale merge point. Three executors caught that one only by
    noticing. It repairs nothing on its own, and it cannot merge, rebase or fetch
    inside the worktree.

    Known gaps

    I wrote these into CHANGELOG.md under [1.4.0] rather than leaving you to find
    them. Markdown decoration inside a frontmatter value that touches neither
    boundary still resolves silently, and I cannot flag an interior backtick
    without also flagging lib/a`b.mjs, which has to stay clean. Closing that
    means stating one rule about markdown in values, not adding a sixth arm.

    727 tests, tsc --checkJs clean on Node 22 and 24, self-verify clean.

    Install

    /plugin marketplace add https://github.com/crenshawdev/cadence.git
    /plugin install cadence@cadence
    

    Full Changelog: https://github.com/crenshawdev/cadence/compare/v1.3.1...v1.4.0

    Downloads
  • v1.3.1 eadc2dcff8

    crenshawdev released this 2026-07-27 16:48:53 +00:00 | 1501 commits to main since this release

    Downloads
  • v1.3.0 9db8dfe459

    v1.3.0 Stable

    crenshawdev released this 2026-07-24 20:06:26 +00:00 | 1587 commits to main since this release

    Signed by john
    GPG key ID: 693AB15F91734B0C
    Downloads
  • v1.2.1 e873d291b4

    Cadence 1.2.1 Stable

    crenshawdev released this 2026-07-23 15:23:33 +00:00 | 1601 commits to main since this release

    Signed by john
    GPG key ID: 693AB15F91734B0C

    Three high-severity fixes from a post-1.2.0 cross-model review sweep over the
    executable seams. All three corrupted state or weakened protection while
    reporting success - the silent class the sweep was hunting. Each ships with a
    regression test written failing-first.

    Fixed

    • A newline in verifier-authored UAT text can no longer flip a verdict.
      renderUat flattens every field value to one line on write, so an evidence
      string containing "\nstatus: pass" stays inert instead of reparsing as a
      second status line where last-assignment-wins silently turned a failed item
      into a pass and opened the phase gate. (#35)
    • renumber insert no longer corrupts the phase directories when the
      highest phase is a decimal insertion.
      The dir-move ceiling is computed
      over integer phases only, so with a 2.1 present the countdown visits the
      integer dirs it must shift and leaves the decimal dir untouched - previously
      it did the exact opposite and still reported ok. (#36)
    • git-guard honors the config it documents. on_protected: "deny" now
      hard-blocks as an alias of refuse (it previously fell through to a soft
      ask), and a lone-string protected_branches guards the named branch instead
      of silently reverting to ['main','master'] - in git-publish too. (#38)
    Downloads
  • v1.2.0 4546cab702

    Cadence 1.2.0 Stable

    crenshawdev released this 2026-07-23 03:44:57 +00:00 | 1608 commits to main since this release

    Signed by john
    GPG key ID: 693AB15F91734B0C

    The judgment-sharpening cycle, dogfooded on Cadence itself. It repairs the
    cross-model review seam so a second opinion actually fires instead of silently
    no-opping, sharpens how the planner splits work and how context decides which
    decisions are worth remembering, adds an on-demand way to stress-test one
    load-bearing decision, and grows the cross-model roster with DeepSeek.

    Cross-model review, repaired

    • The run-as-script guard now compares realpaths on both sides, so
      review-provider.mjs no longer no-ops when the plugin is installed through a
      symlink - cross-model review / consult / detect-models reach the real
      provider instead of degrading to the subagent unnoticed. A symlink regression
      test invokes the script through a link and asserts a non-empty JSON line.
    • An empty or unusable provider result surfaces one line in the caller
      before falling back to claude-subagent, rather than degrading silently.

    Sharper planning and context

    • cad-planner carries a standing separation-of-concerns nudge - a
      heuristic, not a hard rule - that prefers small single-purpose tasks over a
      shared core and splits responsibilities that differ on trigger, size,
      lifecycle, failure-resume, freshness, or ownership. It applies to every plan
      with no per-phase restatement and never forces a split that does not earn
      itself.
    • cad-context marks a decision durable only when it passes a three-part
      filter
      (hard-to-reverse, surprising-without-context, and the result of a
      real trade-off). Durable decisions are written under a ## Durable decisions
      heading and resurface via recall; the phase-local rest stay under
      ## Decisions. Legacy CONTEXT.md files with only ## Decisions still
      resurface unchanged - no retrofitting.

    Decision review

    • /cad-decision-review <path> runs an on-demand refute-then-adjudicate
      pass over one load-bearing decision (a CONTEXT.md line or a PROJECT.md Key
      Decisions row) through the existing review subsystem. cad-reviewer - and a
      cross-model provider when one is configured - refutes the decision; the main
      model grounds each objection against Context7 (library/API claims) and the
      real codebase, then rules it survives | partial | refuted with a concrete
      amendment list. It never auto-fires and reports its cost qualitatively. New
      review.decision_review.{tier,effort} config governs the model.

    DeepSeek cross-model provider

    • DeepSeek is a third cross-model review provider, via its own Chat
      Completions adapter (not an OpenAI Responses base-URL swap). Because DeepSeek
      has no server-side json_schema, the adapter uses json_object mode with the
      finding schema injected into the prompt and the shared validate-on-return
      guard, so a schema-ignoring response degrades to a structured bad-shape
      rather than bad data. reasoning_effort maps the effort dial and keys resolve
      via DEEPSEEK_API_KEY, never logged. Selectable through review.reviewers
      and review.providers.deepseek.tiers.*.
    Downloads
  • v1.1.0 7f6e98eac3

    Cadence 1.1.0 Stable

    crenshawdev released this 2026-07-17 21:05:18 +00:00 | 1646 commits to main since this release

    Signed by john
    GPG key ID: 693AB15F91734B0C

    The stable 1.1.0, promoting the rc.1 and rc.2 line to a public release. The
    full feature detail lives in those two entries below - recall, measured context,
    the two-tier git model, and the release lifecycle all shipped there and carry
    forward unchanged.

    This final round closed the one acceptance the candidates could not: the
    autonomous close (git.auto_close) was exercised live end-to-end against the
    real remote - audit, tag, PR, merge, then reset to a pulled base with the merged
    integration branch reaped - confirming the close chain the rc.2 tests proved in
    isolation also holds in a real publish. The never-auto-push rail via the
    git-publish seam stays intact; auto_close remains opt-in and off by default.

    Full rc.1/rc.2 feature detail: CHANGELOG.md.

    Downloads