Releases: manehorizons/cadence
Release list
v1.50.0
Package Changelog
Minor Changes
-
30cd195: Adds
cadence verify phase [phase] [num]— a state-independent, phase-scoped re-derivation of whether a settled phase's recorded AC coverage still holds against the current working tree, using only the phase's committedDRAFT.mdandSUMMARY.json(no active loop state required). The coverage rescan is scoped to the phase's own declared task files, closing a cross-phaseAC-Ntoken collision that an unscoped repo-wide scan would otherwise be vulnerable to.--changed --base <ref>discovers phases viagit difffor CI use; the optionalverification.testCommandre-run reports a separate, suite-wide (not per-AC) pass/fail signal.Adds
cadence init --ci, which scaffolds a GitHub Actions workflow callingcadence verify phase --changedon every pull request, plus prints (never executes) agh apirecipe to make that check required on the default branch. Closes rec-20260709-003. -
42deb4b: Adds
cadence next, a read-only command that answers "what now?" deterministically from live loop state at any position — 1-3 ranked legal moves with exact commands, plus a stable--jsoncontract ({schemaVersion: 1, position, remainingTasks, blockedOn, legalMoves[]}) for agent orchestrators. Sourced from an extendednextAction()(packages/core/src/progress.ts), which now also computes rankedlegalMoves[]alongside its existing{command, reason}shape — strictly additive;cadence progressandcadence quickstartare unchanged. Closes rec-20260721-002.Registers
/cadence-nextas the 15th Claude Code slash command and the matching Codex prompt command (both host adapters share theCOMMAND_GUIDANCEcatalog in@manehorizons/cadence-types).Also narrows
cadence status --jsonandcadence quickstart --json'snextfield to{command, reason}explicitly — both were passingnextAction()'s full return through unnarrowed, so the newlegalMoves[]array would otherwise have silently leaked into those two commands' existing public JSON contracts (mirrors the narrowingcadence progressalready had). -
b2b8b6b: Empty-result and refusal messages across the intelligence-layer CLI surface (
cadence recommend,cadence milestone propose,cadence recommendation promote/convert/list,cadence retro) now state why the result is empty, the concrete unmet precondition, the nearest-miss candidate from the already-loaded ledger, and the exact command that would change the outcome — closing rec-20260721-001.Adds a shared
findNearestCandidateshelper (packages/core/src/intelligence/nearest-candidate.ts, extracted fromcadence next's existing ranking logic with no behavior change) as the preferred mechanism for "nearest eligible candidate" lookups, so a message's suggestion never diverges fromcadence recommend/cadence next's own ranking.cadence milestone proposegets this enrichment on both the CLI and the MCP-tool (cadence_milestone_propose) surfaces, keyed on "zero milestones newly proposed this run" rather than "the ledger is empty" so it still fires correctly when older accepted/deferred/exported milestones already exist.cadence recommendationnot-found errors (5 near-duplicate sites) are consolidated behind one message builder with a nearest-ID suggestion; its 7 promote/convert status-refusal sites now append the exact unblocking command to their existing status text.cadence retronow distinguishes "no settled phases yet" from "phases scanned, zero friction found" instead of one ambiguous message for both.docs/concepts.mddocuments the four-part invariant (why / precondition / nearest candidates / exact command) as the guidance bar for future intelligence-layer commands. -
a09ee46: Adds
cadence milestone reopen <id>, a CLI transition that moves adeferredmilestone back toproposedso its claimed recommendations become eligible for re-clustering again. PreviouslyapplyTransition()had no path out ofdeferred—clusterMilestones()treats any non-proposedmilestone as a permanent survivor and permanently excludes its claimedrecommendationIds, so a deferred milestone stayed stuck forever with no CLI recourse short of hand-editingmilestones.json.reopenrefuses loudly (exit 1, no state mutation) if the milestone isn't currentlydeferred(naming its current status), the id doesn't exist, or the milestone's claimed recommendation(s) collide with another still-live (non-deferred/non-proposed) milestone. -
6e774d5: Adds an opt-in
<id>-UI-SPEC.mdartifact, sibling to the existing pre-DRAFTSPEC.md, for a phase that touches UI surfaces.cadence spec new --uiscaffolds it with a fixed shape — per-componentLayout & TokensandPrecedent Referencesnested under each### <Component>, plus a whole-sliceResponsive & Interactionsection — so a design contract can be locked down before DRAFT tasks are written, closing rec-20260711-004.cadence spec approveruns a new convergentui-spec-reviewgate after the existingspec-reviewgate, only when a sibling UI-SPEC is present: samenextConvergenceprimitive, its own<id>-UI-SPEC-REVIEW.jsonsidecar, its own unconditionalui-spec-review-unconvergedanomaly, and its own independent--allow-ui-spec-review-failurebypass flag.cadence draft newseeds an approved UI-SPEC's content into a new## UI ContractDRAFT section (bold-text rendering, no nested headings) between Acceptance Criteria and Tasks.No new loop position and no
state.jsonschema change — opt-in purely by the UI-SPEC file's own presence, the same pattern the SPEC stage itself uses. The newuiSpecReviewconfig key is wired intocadence config explainandcadence activatealongside the other six provider blocks.
Patch Changes
Published Packages
All public packages are published on npm as 1.50.0:
@manehorizons/cadence-core@manehorizons/cadence-host-claude-code@manehorizons/cadence-host-codex@manehorizons/cadence-types
Verification
- npm publish completed with provenance in the Release workflow.
- Remote tag
v1.50.0is verified before the GitHub Release is created. - npm package versions and GitHub Release metadata are verified after publish.
- Workflow run: https://github.com/manehorizons/cadence/actions/runs/29940930374
v1.49.0
Package Changelog
Minor Changes
- e0b7f44: Adds
cadence summary render <phase> <num>, a read-only CLI command that reads a settled phase's<id>-SUMMARY.json, validates it against theSummaryZschema, and prints a deterministic Markdown rendering (per-AC pass/fail with evidence level, per-task status, gate outcomes, gate bypasses, decisions, deferred items — empty sections omitted entirely) suitable for pasting into a PR description or comment. Refuses loudly with a distinct stderr message and non-zero exit for each of three failure modes (missing file, invalid JSON, schema-validation failure) rather than crashing or printing a partial render. Addsdocs/team-rollout.md, a guide for adopting CADENCE across a team in PR review without replacing existing CI or human review.
Published Packages
All public packages are published on npm as 1.49.0:
@manehorizons/cadence-core@manehorizons/cadence-host-claude-code@manehorizons/cadence-host-codex@manehorizons/cadence-types
Verification
- npm publish completed with provenance in the Release workflow.
- Remote tag
v1.49.0is verified before the GitHub Release is created. - npm package versions and GitHub Release metadata are verified after publish.
- Workflow run: https://github.com/manehorizons/cadence/actions/runs/29762921101
v1.48.0
Package Changelog
Minor Changes
- 60b7b5a: Adds a CLI writer for a milestone's operator-authored pre-mortem fields (closes rec-20260714-001):
cadence milestone premortem <id>now accepts repeatable--add-out-of-scope <text...>,--add-likely-failure-mode <text...>, and--add-hidden-dependency <text...>options that append operator-authored text without hand-editing.cadence/intelligence/milestones.json. Each value is refused (non-zero exit, clear stderr, nothing written) if empty or whitespace-only after trimming. Operator-authoredlikelyFailureModes/hiddenDependenciesentries now survive a later plaincadence milestone premortem <id>refresh alongside the freshly-derived deterministic entries, mirroring the guaranteeoutOfScopealready had. All operator-supplied text is newline-collapsed to a single line before being stored, matching how every other pre-mortem entry in the ledger is normalized (a raw embedded newline would otherwise breakMILESTONES.md's one-bullet-per-entry rendering). - 7cc606d: Adds
cadence recommendation evidence add <recId> --note <text>, a tied-record writer that appends a new evidence note to an existing recommendation and links it into the recommendation'sevidenceIds. Previously the only way to attach evidence after a recommendation's creation was a manual hand-edit ofevidence.jsonandrecommendations.jsonin lockstep —cadence intelligence reconciledoes not help here, sincederiveRecommendationLinksonly re-derivesassumptionIds/decisionIdsfrom the assumption/decision ledgers, neverevidenceIdsfrom the evidence ledger, so a hand-added evidence entry silently would not show up incadence recommendation showuntilevidenceIdswas also hand-edited. The new command writes both ledger files atomically in one call, redacts secret-shaped substrings in the note the same wayrecommendation add --evidencedoes, and refuses cleanly (no ledger mutation) on an unknown recommendation id. - ac6722c: Fixes
.cadence/state.json/STATE.mdtracked-file cross-worktree merge conflicts (#177):cadence initnow gitignores the four CADENCE-owned ephemeral paths (state.json,STATE.md,mcp-trust.json,intelligence/context/) by default, andcadence doctor/cadence doctor --fixgain astate-trackedcheck +untrack-stateauto-repair to migrate existing repos (this repo included). The audit-trail value a trackedstate.jsonused to carry incidentally now lives in a newstateAtSettlefield onSUMMARY.json/SUMMARY.md, captured immediately before each settle resets the loop toIDLE.cadence doctoralso diagnoses an unresolved git conflict instate.jsonwith a field-by-field local/incoming diff instead of a bare JSON-parse error, andcadence doctor --fix --resolve-state-conflict=local|incomingwrites the chosen side through the normal state-commit path. Any command that hits a corruptedstate.jsonnow prints a pointer tocadence doctor --fixinstead of a bare error.docs/concepts.md,CLAUDE.md, anddocs/reference/commands.mdare updated to describe the new convention.
Patch Changes
- 7a9098a: Fixes a ReDoS-shaped regex-injection risk (#249, CodeQL) in
cadence assumption list,cadence decision list, andcadence recommendation list:--filter-regexvalues were compiled directly withnew RegExp(...)with no bound on pattern length, so a pathologically long attacker- or script-supplied pattern could hang the process. Each command now rejects patterns longer than 200 characters with a clear<command> list failed: --filter-regex pattern is too long: ...stderr message and non-zero exit, beforenew RegExpis ever called — legitimate, previously-accepted patterns (well under the cap) are unaffected. The guard is duplicated per-command rather than factored into a shared helper, matching this codebase's existingparseRegexFlagsprecedent.--filter-regex's--helptext anddocs/reference/commands.mdare updated to document the length limit. - 9dd68f8: Fixes
cadence onboardsilently no-op'ing on a.cadence/dir with a missingstate.json(#177 fallout from phase 196'sstate.json/STATE.mdgitignoring): a freshgit worktreeor a fresh clone of a repo with.cadence/already committed has nostate.jsonyet, butonboard— the command built exactly for "a repo that already has.cadence/committed" — previously read it for the project name, fell back to"unnamed"on the missing file, and never wrote one, leaving every subsequent state-reading command (cadence progress, etc.) throwNotInitializedErrorright afteronboardreported success.onboardnow bootstraps a freshstate.json(loopPosition: IDLE, no active phase/draft/task,revision: 0) whenever one is missing, deriving the project name from.cadence/PROJECT.md's header rather thanpackage.json(which can disagree with the recorded project name in a monorepo), and prints a loud stderr notice when it does. An existingstate.jsonis left completely untouched.cadence doctor's missing-state.jsondiagnostic now namescadence onboardas the fix instead of advice that no longer worked (cadence initcorrectly refuses on an already-.cadence/-committed repo).docs/reference/commands.md'sonboardbehavior section is updated to describe both the bootstrap and pass-through paths. - 2acd4c0: Fixes a bug (#248) where
cadence recommendation addcould reuse an already-issued recommendation ID once every recommendation created on a given day had been archived (e.g. shipped).nextRecommendationIdonly scanned the activerecommendationsarray for the highest existing same-day sequence number, never thearchivedbucket — once the active array had no same-day entries left, the counter reset to001and collided with the first ID issued that day, even though that ID remained in permanent use elsewhere (evidence, assumptions, decisions, milestone links, commit messages, DRAFT files). New recommendation IDs are now guaranteed unique across a project's full history, not just among currently-active entries. - 14c7336: Adds a
task-verify-requiredsettle gate that refusescadence settle runwhen a task is marked DONE but its DRAFT- verify:line was empty or omitted — previouslydraft-parser.tssilently defaulted a missing line to''and SUMMARY.md recorded a bareTN: DONEwith zero evidence (#206). The gate fires instandard/complextiers acrossstrict/standard/autoprofiles;quick-fixis deliberately exempt. The refusal names every offending task id and points at the missing verify line, following this repo's refuse-and-suggest house style — it never mutates the DRAFT or task status.docs/concepts.mdandcadence explain gatesare updated for the new 14-gate total.
Published Packages
All public packages are published on npm as 1.48.0:
@manehorizons/cadence-core@manehorizons/cadence-host-claude-code@manehorizons/cadence-host-codex@manehorizons/cadence-types
Verification
- npm publish completed with provenance in the Release workflow.
- Remote tag
v1.48.0is verified before the GitHub Release is created. - npm package versions and GitHub Release metadata are verified after publish.
- Workflow run: https://github.com/manehorizons/cadence/actions/runs/29710894999
v1.47.0
Package Changelog
Minor Changes
- a786395:
cadence dispatch plangave no per-task signal about whether a dispatched task should run in its own isolated worktree — isolation was decided purely by human/skill-level convention, with no backing in the dispatch plan itself. Per rec-20260718-002 (from the same 2026-07-18 incident that motivated the dispatch-packet action-class prohibitions), every task in a dispatch plan now carries arecommendedIsolationvalue of'worktree'or'none':'worktree'when the task declares one or morefiles:(it will mutate the working tree),'none'when it declares none (read-only/no mutation expected). This is surfaced both as a newrecommendedIsolationfield incadence dispatch plan --json's per-task output and as an advisory line in the rendered packet text itself — purely additive, noTask/Draftschema change, and no enforcement mechanism.
Patch Changes
- 3b03250:
cadence dispatch plan's rendered packet (renderPacket) previously told the dispatched implementation agent to self-record its own outcome viacadence build task <id> --status=...— the only thing scoping its behavior was afiles:boundary. A real incident (2026-07-18) showed the gap: a dispatched fork agent overran its scoped task, rancadence build/cadence settleandgit commitdirectly againstmainfour times, self-authorized without the orchestrator's review. Every rendered packet now includes a mandatory prohibition block forbidding state-mutatingcadencesubcommands (cadence build,cadence settle, etc.),git commit/git push,gh/network actions, and invokingAskUserQuestion— the dispatched agent must stop and report to the orchestrating session once its verify condition is met (or it's blocked); the orchestrator alone records the task outcome. - 57eb46b: Fixes
cadence settle rundeterministically failing withStateConflictErrorwhenever ahost-cliverifier gate (whose subprocess can run for minutes) overlapped another subagent'sSubagentStophook — the hook's telemetry-onlysession.subagentSpawns += 1was routed through the same revision-guardedSimpleStateBackend.commit()as structural writes, so every spawn bump invalidated any other command's in-flight snapshot and the failure never converged on retry (#234).StateBackendgainsbumpSessionCounter(), a write path scoped to purely-informationalsessioncounters that never compares to or bumps the optimistic-concurrencyrevisionfield;handleSubagentResult()'s telemetry-only branch now uses it. Structural commits (loop position, tasks, drafts, decisions, subagent baselines) keep the exact same revision-guarded conflict behavior as before.
Published Packages
All public packages are published on npm as 1.47.0:
@manehorizons/cadence-core@manehorizons/cadence-host-claude-code@manehorizons/cadence-host-codex@manehorizons/cadence-types
Verification
- npm publish completed with provenance in the Release workflow.
- Remote tag
v1.47.0is verified before the GitHub Release is created. - npm package versions and GitHub Release metadata are verified after publish.
- Workflow run: https://github.com/manehorizons/cadence/actions/runs/29661224299
v1.46.0
Package Changelog
Minor Changes
- 7c5f4ff: Add
cadence onboard, a one-command setup for the 2nd-Nth teammate cloning a repo that already has.cadence/committed: it installs host hooks (reusingcadence init's host-wire logic, now shared viainit/host-wire.ts), reports the existing project's name and gate profile, and reports provider/API-key readiness — without re-scaffolding.cadence/config.jsonorstate.json. Refuses cleanly with a pointer tocadence initwhen no.cadence/is present.cadence initnow also seeds a managedCONTRIBUTING.mdblock pointing new contributors atcadence onboard, so the path is discoverable. Fulfils rec-20260709-005. - 3e9319e: Add
cadence retro, a read-only cross-phase rollup over every settled phase's post-settle retro artifact (.cadence/phases/*/*-RETRO.json). It aggregates gate-bypass names, rough-task statuses, and code-review/security-audit/boundary-scan finding categories across all scanned phases, splitting each dimension into a recurring bucket (2+ phases) and a one-off bucket (exactly 1 phase) so friction that keeps showing up isn't buried under single-occurrence noise. Supports--format terminal|json(defaultterminal), mirroringcadence intelligence stats's format-flag and exit-code conventions; never writes tostate.json,STATE.md, or any phase artifact.@manehorizons/cadence-typesgains additiveRetroRollupZ,PhaseRetroEntryZ,RetroFrequencyEntryZ, andRetroFrequencyBucketsZschemas (and their inferred types) backing the rollup shape. Fulfils rec-20260712-002. - 499558f:
cadence doctor --fixnow auto-remediates thehandoff-retentioncheck: whenhandoff.retainis unset and the.cadence/handoff/SESSION-doc archive has grown past the existing warn threshold,--fixsetshandoff.retainto the default (10) and immediately prunes the archive down to that budget, reusing the existingpruneHandoffDir/selectPrunableretention primitives and always preserving the activelastHandoffdoc. Previously this check only printed guidance. Fulfils a narrowed slice of rec-20260709-002; the other manual doctor checks (worktree-phases,verification-readiness,recommendation-shipped-drift,coverage-mode-language-support) remain manual since each requires a genuine judgment call--fixcannot safely auto-decide. - eecc525: Wire a real
hostClibuilder into the 5 verifier families phase 165 left unwired:spec-review,plan-review,code-review,security-audit, and deep-verify (Verifier). Onlyper-task(phase 165 T7) had a workinghost-cliprovider — every other family withprovider: "host-cli"set in.cadence/config.jsonwas silently falling back tomock(a deterministic placeholder, not real verification) regardless of config, sincecreateVerifierFactory's generichost-clidispatch only activates when a family supplies ahostCli()builder. AddsHostCliSpecReviewVerifier,HostCliPlanReviewVerifier,HostCliCodeReviewVerifier,HostCliSecurityAuditVerifier, andHostCliVerifier, each spawning the configured host CLI (claude/codex) headlessly via the existinghostCliJSONtransport — same pattern asHostCliPerTaskVerifier, no new dependency.cadence doctor's verification-readiness claim for theverifierseam ("deep-verify uses host-cli with credentials present") is now actually true instead of coincidentally true. - 749fd2d: Add
cadence init --full, a one-command full setup that composes the existing--wire-host,--demo, and--activateflags: when their preconditions are met it wires the detected host with no prompt, seeds the01-demophase, and activates real verification whenANTHROPIC_API_KEYis present — printing one consolidated "Full setup summary" (done/skipped-with-reason per feature) in addition to the existing per-feature messages. Any explicitly-passed flag, including--skip-host-wire, still overrides its--full-implied default. Barecadence initwith no flags is unchanged. Fulfils rec-20260709-001.
Patch Changes
- 42dc58f: Fix
--allow-auto-complexsoft-cap overrides being invisible inSUMMARY.jsonand the real-time anomaly-notify transport. Settling a phase under the auto×complex soft cap with--allow-auto-complexnow records a{ gate: 'soft-cap', flag: '--allow-auto-complex', severity: 'warn' }entry inSUMMARY.json'sgateBypasses, andcadence draft approve --allow-auto-complexnow emits a newauto-complex-overrideAnomalyEventthrough the anomaly-notify transport (mirroringcoherence-warn) when theanomaly-notifygate is active.@manehorizons/cadence-typesgains the additive'auto-complex-override'value onAnomalyTypeZ. - Updated dependencies [3e9319e]
- Updated dependencies [42dc58f]
- @manehorizons/cadence-types@1.46.0
Published Packages
All public packages are published on npm as 1.46.0:
@manehorizons/cadence-core@manehorizons/cadence-host-claude-code@manehorizons/cadence-host-codex@manehorizons/cadence-types
Verification
- npm publish completed with provenance in the Release workflow.
- Remote tag
v1.46.0is verified before the GitHub Release is created. - npm package versions and GitHub Release metadata are verified after publish.
- Workflow run: https://github.com/manehorizons/cadence/actions/runs/29626630135
v1.45.0
Package Changelog
Minor Changes
- 90364bb: Add an MCP tool-trust envelope constraining
cadence_draft_approveandcadence_spec_approve— the two MCP tools where the tool call itself previously acted as the approval, with no expiry, capability scope, or revoke logic. Each of the 18 registered MCP tools is now tagged with acapabilityClass(READ_ONLY|LEDGER_WRITE|LOOP_WRITE|APPROVAL_BYPASS|SETTLE); the twoAPPROVAL_BYPASStools now refuse (naming the failing check, before anystate.jsonwrite) unless the caller holds a trust grant that matches the tool's live structural def-hash (name + description + inputSchema), was issued for the running CADENCE version, and has not expired. Grants are issued exclusively via a new CLI-only command family —cadence mcp trust grant --tool <name> [--ttl-days <n>],cadence mcp trust revoke --tool <name>,cadence mcp trust list— never reachable from any MCP tool call, so an MCP client can never self-grant approval-bypass trust. Grants are stored in a new operator/machine-local.cadence/mcp-trust.jsonledger (gitignored, not shared repo state likestate.json).cadence_settleis classifiedSETTLEbut deliberately left ungated this phase. Seedocs/concepts.md's new "MCP tool-trust envelope" section anddocs/reference/commands.md'smcp trustentries for full detail. - 424aa8c: Add
cadence milestone status <id>, a read-only reconciliation command that maps a milestone's converted recommendations to their phases, resolves each phase's owning worktree (local or sibling) viagatherHandoffCandidates, and reports that worktree's live loop position — replacing N manualcadence statusround-trips with one. Recommendations not yet converted to a phase, and converted phases with no matching worktree, are reported (asnot-yet-converted/no-worktree-found) rather than dropped. Supports--json; refuses with exit 1 for an unknown milestone id, matching the existingaccept/defer/closerefusal shape. Never writes to any ledger,state.json, or worktree.
Patch Changes
- 5b426dd: Thread an optional
{ signal?: AbortSignal; traceId?: string }through the verifier call path so long verifier runs can be cancelled cleanly and correlated via a trace id in logs.host-cli-client.ts's headless-CLI subprocess spawn now honors an externalAbortSignal(killing the child and rejecting with a newHostCliErrorreason'aborted', distinct from the existing'timeout') alongside its existing internal spawn-timeout timer.Verifier.verifyandSecurityAuditVerifier.verifyboth gain the same optional second parameter —LocalVerifier/LocalSecurityAuditVerifierforwardsignalinto the underlyingfetch/localChatJSONcall,AnthropicSecurityAuditVerifierforwardssignalinto the Anthropic SDK's request options, andMockVerifier/MockSecurityAuditVerifieraccept-and-ignore it. Thesecurity-auditgate now generates a fresh per-run trace id and passes it through end-to-end as a concrete proof the plumbing is connected, not just added-and-unused. Purely additive: every existing call site that omits the new parameter keeps compiling and behaving exactly as before.local-client.ts's network-error handling now also preserves the original error via{ cause }and includes its name in the message, so an aborted call can be told apart from a genuine network failure. Scoped topackages/core/src/gates+security-audit.ts's verifier hierarchy per rec-20260712-010; the same pattern is left for a future phase to apply toPerTaskVerifier/CodeReviewVerifier/PlanReviewVerifier/SpecReviewVerifier. - 462f239: Harden the
host-cliverifier provider against three risks: invisible consumption of the host CLI's own subscription/usage quota during verification calls, an unguarded self-invocation path whencadenceitself is already running inside the same host CLI it would spawn, and a subprocess hang when the spawned process never exits.hostCliJSONnow emits a one-time-per-process stderr notice on the first real spawn (never on provider selection alone); refuses to spawn — falling back tomockvia the existing per-call fallback path — when theclaudefamily's session env var (CLAUDECODE=1) indicates cadence is already running inside a headlessclaudesession (codexhas no reliable documented equivalent and is left unguarded); and bounds the spawn with a configurableCADENCE_HOST_CLI_TIMEOUT_MStimeout (default 3 minutes) that kills a hung subprocess and rejects with a newHostCliError(reason: 'timeout')instead of hanging forever. Seedocs/providers.md'shost-clisection for full operator-facing detail, including the consequence thathost-clicalls always fall back tomockwhencadenceruns from inside a Claude Code terminal, hook, or Bash tool call. - c8b197a: Redact secrets/credentials from persisted intelligence-ledger and security-audit output.
Evidence.summary(free-text quotes attached viaaddRecommendation'sevidenceSummary) andsecurity-auditgateFinding.message(bothSUMMARY.securityAuditand the per-critical stderr log) now pass through a newredactSecretsutility before being written, replacing AWS access keys, GitHub tokens, bearer/basic Authorization header values, JWT-shaped strings, PEM private-key blocks, and generickey=/token=/password=/secret=assignments with[REDACTED]. The four intelligence ledger JSON files (recommendations.json,evidence.json,assumptions.json,decisions.json) are now also written with0o600(owner-only) file permissions, applied atomically at file-creation time rather than via a create-then-chmod race. - Updated dependencies [90364bb]
- @manehorizons/cadence-types@1.45.0
Published Packages
All public packages are published on npm as 1.45.0:
@manehorizons/cadence-core@manehorizons/cadence-host-claude-code@manehorizons/cadence-host-codex@manehorizons/cadence-types
Verification
- npm publish completed with provenance in the Release workflow.
- Remote tag
v1.45.0is verified before the GitHub Release is created. - npm package versions and GitHub Release metadata are verified after publish.
- Workflow run: https://github.com/manehorizons/cadence/actions/runs/29451252247
v1.44.1
Package Changelog
Patch Changes
- Fix a gate implementation's thrown exception escaping uncaught out of
runSettleGatestosettle.ts's outer catch, which printed to stderr and exited 1 with noSUMMARYwritten —security-auditwas previously the sole gate normalizing its own throws into arefuseoutcome. The gate invocation inrunSettleGatesis now wrapped centrally, so any of the other 8 gates throwing produces the same synthesized{outcome: 'refuse', reason}plus a'refused'provenance entry, flowing through the existing refusal path that persistsSUMMARY.json/SUMMARY.mdand leaves loop state untouched. Closesrec-20260712-007. - e38d86a: Add optimistic concurrency to
SimpleStateBackend.commit()to prevent lost updates when twocadencestate writers (CLI commands, hooks, or the MCP server) race on.cadence/state.jsonin the same checkout — the actual failure mode behind a recent incident where two concurrent Claude Code sessions in one primary checkout stomped each other's uncommitted work.CadenceStategains arevision: numberfield (additive,.default(0), back-compat with pre-existingstate.jsonfiles).commit()now compares the current on-disk revision to the caller's in-memorystate.revisionbefore writing: a match bumps it in place and writes as before; a mismatch refuses with a newStateConflictError(naming both revisions) instead of silently overwriting the other writer's change, unless the new{ force: true }option is passed (which overwrites unconditionally and warns loudly to stderr). A bootstrap write (no existingstate.json) skips the check entirely. The in-place revision bump means a caller issuing several sequentialcommit()calls on the same in-memory object — e.g. a hook handler with two independent write branches — stays in sync automatically without re-reading between calls. - 6fc52bd: Add a post-settle retro artifact and an interactive GitHub issue offer (rec-20260712-001). On every successful
cadence settle, a friction digest — gate bypasses, tasks whose terminal status wasn't a cleanDONE, and any code-review/security-audit/boundary-scan findings — is synthesized purely from the SUMMARY data already assembled and written as<draftId>-RETRO.json/.mdalongsideSUMMARY.json/.md(a clean settle writes a "No friction detected this settle." form).@manehorizons/cadence-typesgains an additiveRetroDigest/RetroDigestZschema and aretro: { enabled, offerGithubIssue }config block (both defaulttrue, same shape convention as the existingrecommendationsblock). When the digest is non-empty and the run is interactive (a real TTY, or theCADENCE_PROMPTER_SCRIPTtest seam), settle also offers to file a GitHub issue for it viagh— resolving and naming the actual target repo before asking (gh repo view), creating the issue non-interactively with an explicit--repo, then best-effort labeling itneeds-triagein a separate call so a repo without that label can't fail issue creation outright. The offer runs strictly after the loop's state commit, never before, so an open prompt can never strand the loop mid-BUILD. A duplicated prompter-factory closure (previously independent copies insettle.tsandhandoff/run-resume.ts) was consolidated into one sharedcreateDefaultPrompter()inverify/prompter.tsas part of this work — see that function's doc comment for a documented, narrow known limitation around scripted settle runs that fire both the interactive-verdict gate and a friction-having retro offer in the same process. - c5cd4b0: Fix a refusing settle gate silently dropping out of
gatesprovenance and a refusedsettle runwriting noSUMMARYat all — previously the only trace of a refusal was an ephemeral stderr line.GateProvenanceZ.statusgains a'refused'value plus an optionalreasonstring (additive, back-compat with pre-existingran/skippedrecords); all 9 settle-dispatched gates (draft-read,structural-verifier,boundary-scan,build-test-must-pass,test-coverage,interactive-verdict,deep-verify,code-review,security-audit) now attachreasonmatching their stderr text on refusal, andrunSettleGatespushes the refusing gate's entry ontogatesbefore halting. A refusedcadence settle runnow persistsSUMMARY.{json,md}(populatedgatesthrough the refusing entry, realtaskResults, emptyacResults/decisions/deferred) without transitioningloopPosition/activeDraft, so the loop stays exactly where a human can retry. - Updated dependencies [e38d86a]
- Updated dependencies [6fc52bd]
- Updated dependencies [c5cd4b0]
- @manehorizons/cadence-types@1.44.1
Published Packages
All public packages are published on npm as 1.44.1:
@manehorizons/cadence-core@manehorizons/cadence-host-claude-code@manehorizons/cadence-host-codex@manehorizons/cadence-types
Verification
- npm publish completed with provenance in the Release workflow.
- Remote tag
v1.44.1is verified before the GitHub Release is created. - npm package versions and GitHub Release metadata are verified after publish.
- Workflow run: https://github.com/manehorizons/cadence/actions/runs/29217246161
v1.44.0
Package Changelog
Minor Changes
- e3179cf: Add real assertion-mode test-coverage span parsing for Python, Go, Rust, and PHP (previously js/ts only), plus an operator-extensible escape hatch for any other language.
- A shared, profile-parameterized scanning engine (
packages/core/src/verify/coverage-profiles/) replaces the old hardcoded JS/TS-only scanner. Four block-boundary strategies — call-expression, brace-delimited, indentation-delimited, and do-end-keyword — cover every built-in profile and remain available to custom ones. - Five built-in language profiles ship: js/ts (re-expressed, byte-identical behavior to before), python (pytest-style, including
async def), go (func TestX(t *testing.T), table-driven tests, testify), rust (#[test]/#[should_panic], unbounded raw strings), and php (both Pest closures and PHPUnit methods, including heredoc/nowdoc-safe masking). verification.coverageProfileslets an operator define a custom profile (opener/assertion patterns, comment/string syntax, block strategy) for any language with no built-in support — validated at config-load time with refuse+suggest diagnostics; custom profiles are add-only and cannot override a built-in's extensions.cadence verify coverage --explain AC-N [--json]is a new read-only diagnostic: which files matched, which profile scanned each one, every span found, and why each did or didn't satisfy assertion mode.- Per-file dispatch is wired into the real
test-coveragegate (scanTestCoverage) — assertion mode now genuinely works end-to-end for all five built-in languages, not just in isolation. The gate's refusal messages are language-neutral and point at the new--explaindiagnostic.cadence init's defaultverification.testGlobsfor rust now also includessrc/**/*.rs, since idiomatic Rust unit tests commonly live inline in a#[cfg(test)] mod tests { ... }block.cadence doctor's coverage-mode language-support check now reflects the live profile registry instead of a hardcoded js-only list. - The false-positive-averse invariant holds throughout: an unrecognized shape always yields zero spans, never a partial or fabricated match. This required closing several real gaps found during review — opener-pattern spoofing via comments, strings, and nested parenthesized sub-expressions (go); an unbounded-hash raw-string masking gap (rust); a standalone-heredoc fabricated-span gap (php); and a cross-process custom-profile collision-shadowing gap (
verification.coverageProfiles).
- A shared, profile-parameterized scanning engine (
Patch Changes
-
a5b21ec: Fix
cadence initdefaultingverification.coverageModeto'assertion'for every project regardless of language, which made thetest-coveragegate permanently unsatisfiable for non-JS/TS projects (the assertion-mode span-finder only recognizes JS/TSit()/test()syntax).cadence initnow detects the project's language from root marker files (package.json→js/ts,pyproject.toml/setup.py/requirements.txt→python,go.mod→go,Cargo.toml→rust,composer.json→php) and only defaultscoverageModeto'assertion'when the detected language is js/ts; every other detected or unknown language defaults to'mention'instead, with a stderr notice explaining why. Existing.cadence/config.jsonfiles are never rewritten.- Default
verification.testGlobsare now language-aware too, somention-mode coverage checking can actually discover test files in non-JS projects (python:**/test_*.py,**/*_test.py; go:**/*_test.go; rust:tests/**/*.rs,**/*_test.rs; php:**/*Test.php,tests/**/*.php). - The
test-coveragegate's assertion-mode refusal message now distinguishes its causes accurately: no test file matched the configured globs at all, vs. files matched but no test references the AC, vs. files matched and reference the AC but not inside an assertingit()/test()block — each with its own suggested fix. cadence doctor(and the MCPdoctortool) now warns whencoverageMode: 'assertion'is paired with a detected project language that has no assertion-mode parsing support yet, suggestingcadence config edit coverageMode.
This does not add real assertion-mode test-span parsing for Python/Go/Rust/PHP — only js/ts has that today. It closes the "permanently unsatisfiable gate" failure mode for every language by making the defaults and diagnostics honest.
-
8bf3135: Fix
test-coveragegate inassertioncoverage mode wrongly treating an AC whose only linked test sits inside atest.skip/.todo/.failingblock as fully covered, even when the block contains an intact assertion. Previouslycadence settle run --autowould settle clean (exit 0) on a skipped test; the gate now refuses with a distinct message ("AC-N's only linked test is skipped") separate from the existing "no linked test" and "mentioned but not asserting" refusals, naming the fix (unskip the test or replace it with a running asserting block) rather than suggesting an unrelatedcoverageModeswitch.findTestSpansnow flagsskip/todo/failingopeners as non-asserting spans (only/concurrentare unaffected, since those execute normally);scanTestCoveragepropagates this through a newskippedflag on each test reference, and a newskippedOnlyLinkedAcsexport is mutually exclusive with the existingweaklyLinkedAcs— an AC only lands in the new bucket when every one of its non-qualifying references is skip-caused.mention-mode coverage is unaffected. -
Updated dependencies [a5b21ec]
-
Updated dependencies [e3179cf]
-
Updated dependencies [8bf3135]
- @manehorizons/cadence-types@1.44.0
Published Packages
All public packages are published on npm as 1.44.0:
@manehorizons/cadence-core@manehorizons/cadence-host-claude-code@manehorizons/cadence-host-codex@manehorizons/cadence-types
Verification
- npm publish completed with provenance in the Release workflow.
- Remote tag
v1.44.0is verified before the GitHub Release is created. - npm package versions and GitHub Release metadata are verified after publish.
- Workflow run: https://github.com/manehorizons/cadence/actions/runs/29167422921
v1.43.0
Package Changelog
Minor Changes
-
Enable
cadence initto prepare a repo for Codex on the first run, so a new
user starting Codex can immediately use Cadence commands without manually
discovering extra adapter setup steps.cadence init --host codex(with--agents-md) now wires host hooks,
generates the project-levelAGENTS.mdguidance, and flows through the
same init path as Claude Code — previously Codex setup only installed
adapter hooks/prompts and skippedAGENTS.mdgeneration.cadence doctorgained Codex readiness checks (hooks, prompts,
AGENTS.md, global command availability), each with an opt-indoctor --fixremediation.- Codex/quickstart/CLI docs point first-time users at
cadence init --host codexinstead of adapter-only setup.
-
d502562: Harden handoff/resume against two gaps ground-truth discovery didn't cover:
a handoff that's stale relative to origin, and a handoff whose narrative was
never finished.cadence resumenow runs a best-effort origin-freshness probe before
replaying a doc (configresume.remoteCheck, defaulttrue;--offline
to skip) and warns when origin has commits this clone lacks, since a
stale handoff can be superseded by work pushed from another machine.cadence resumeandcadence handoff --check(new) both detect
scaffolded<!-- … FILL IN … -->sections left unfilled by a prior
session and flag them —resumeas a warning,handoff --checkas an
exit-3 completion gate.cadence handoff --no-fetchskips the pre-factsgit fetchfor a fully
offline write;git-factsrecords whether the fetch actually ran.- The Claude Code
/cadence-handoffand/cadence-resumeslash-command
guidance text is updated to teach agents the new gate and banner.
-
1351044: Add
host-cli, a 4th verifier provider that shells out to your already-authenticatedclaude/codexCLI in headless mode instead of requiring a separateANTHROPIC_API_KEY.- New provider value
'host-cli'on every provider config slice (verifier,perTaskVerifier,codeReview,planReview,securityAudit,specReview), pluscadence activate --provider host-cliandcadence settle run --verifier host-cli. Binary discovery defaults toclaudeon PATH, overridable viaCADENCE_HOST_CLI_BIN. - If the configured binary is missing or the CLI reports an auth/exit failure, verification for that call transparently falls back to
mockwith a loud stderr warning — never silent, never a hang waiting on interactive auth. - Current scope: only the per-task-verify family (the BUILD-phase task verifier) has a real
host-cli-backed implementation in this release. The other verifier families (deep-verify, code-review, spec-review, plan-review, security-audit) accept the config value but currently fall back to mock with a warning until they're wired in a follow-up.cadence doctor/cadence activatereporthost-clireadiness from config well-formedness alone (no required credential, by design) — not a live probe of the binary; that's only discovered lazily on the first real verification call. Seedocs/providers.mdfor the full picture, including a known no-spawn-timeout gap. - The JSON-extraction + schema-repair-retry logic previously private to the
localprovider is now a shared, transport-agnostic module (json-repair.ts) reused by bothlocalandhost-cli.
- New provider value
-
bef364d: Make verifier activation trustworthy: broader key discovery, a real
activation smoke test, and committed provider config that actually reaches
every real call site.- A verifier API key is now discovered from a
.envfile at the repo root
when it isn't exported into the process environment (discoverKey),
closing the gap where a legitimately-available key was invisible to
cadence activate/cadence doctorunless manuallyexported. cadence activate's live provider check is no longer coincidentally
skippable — when a key is discovered and the provider isn'tmock, the
smoke test runs and its outcome (not mere key presence) gates whether
activation is reported as successful.--no-checkremains the only
explicit opt-out.- The discovered-key path now reaches every real verifier-selection call
site (cadence doctor,cadence settle run's deep-verify/code-review/
security-audit seams, the draft/build gates,cadence spec approve), not
just the primitives — includingcadence mcp serve --repo <path>, where
the server process's own working directory can differ from the repo being
operated on. A teammate who never rancadence activatelocally, but
whose key is discoverable and whose repo already commits a real provider
choice, now gets real verification instead of a silent mock fallback.
- A verifier API key is now discovered from a
Patch Changes
- Updated dependencies
- Updated dependencies [d502562]
- Updated dependencies [1351044]
- Updated dependencies [bef364d]
- @manehorizons/cadence-types@1.43.0
Published Packages
All public packages are published on npm as 1.43.0:
@manehorizons/cadence-core@manehorizons/cadence-host-claude-code@manehorizons/cadence-host-codex@manehorizons/cadence-types
Verification
- npm publish completed with provenance in the Release workflow.
- Remote tag
v1.43.0is verified before the GitHub Release is created. - npm package versions and GitHub Release metadata are verified after publish.
- Workflow run: https://github.com/manehorizons/cadence/actions/runs/29133839785
v1.42.0
Package Changelog
Minor Changes
- Add
boundaryEnforcement: 'warn' | 'block'(defaultwarn, back-compat), overridable per-phase via DRAFT frontmatter. Inblockmode,handlePreToolEditrefuses an out-of-boundary edit at edit time instead of only warning. Fails open (never blocks) when there's no active draft/phase, or when the active draft declares zerofiles:in total. - Add a
boundary-scansettle gate — closes the blind spot edit-timeboundaryEnforcement: 'block'can't see (most notably a subagent-driven edit, invisible to the pre-tool-edit hook). Enumerates every file touched by the whole phase via an unscoped git diff against the integration ref, and refuses settle on a real out-of-boundary offender whenboundaryEnforcementresolves toblock— bypassable via--force/--allow-boundary-scan-failureunless the gate is sealed. - Catch a subagent (or a human) touching a DRAFT task's declared files after that task is already marked
DONE/DONE_WITH_CONCERNS— live at edit time via a newredundantWorkEnforcement: 'off' | 'warn' | 'block'config (defaultwarn, DRAFT-frontmatter overridable), plus aSubagentStartbaseline snapshot + advisory task-board nudge and aSubagentStopsafety net that diffs an agent's touched files against its baseline. - Add
cadence dispatch plan [--json], a read-only CLI command that computes wave-based subagent dispatch groups from the active BUILD draft's task list (a unified topological-leveling pass overdepends:edges andfiles:-overlap prerequisite edges, plus cycle/unknown-dependency detection), and a new/cadence-dispatchClaude Code slash command that drives the host agent through a parallel Task-tool dispatch loop over the computed waves.Taskgains an optionaldepends: string[]DRAFT.md field.
Patch Changes
- Fix
parseSpecMd/parseDraftMdsilently truncating a multi-line Objective or a multi-line Given/When/Then clause at the first line break. Both extractors now capture the full wrapped text; single-line parsing is byte-identical to before. - Updated dependencies
- Updated dependencies
- Updated dependencies
- Updated dependencies
- Updated dependencies
- @manehorizons/cadence-types@1.42.0
Published Packages
All public packages are published on npm as 1.42.0:
@manehorizons/cadence-core@manehorizons/cadence-host-claude-code@manehorizons/cadence-host-codex@manehorizons/cadence-types
Verification
- npm publish completed with provenance in the Release workflow.
- Remote tag
v1.42.0is verified before the GitHub Release is created. - npm package versions and GitHub Release metadata are verified after publish.
- Workflow run: https://github.com/manehorizons/cadence/actions/runs/28841286044