Skip to content

Releases: manehorizons/cadence

v1.50.0

Choose a tag to compare

@github-actions github-actions released this 22 Jul 17:12
83d9c95

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 committed DRAFT.md and SUMMARY.json (no active loop state required). The coverage rescan is scoped to the phase's own declared task files, closing a cross-phase AC-N token collision that an unscoped repo-wide scan would otherwise be vulnerable to. --changed --base <ref> discovers phases via git diff for CI use; the optional verification.testCommand re-run reports a separate, suite-wide (not per-AC) pass/fail signal.

    Adds cadence init --ci, which scaffolds a GitHub Actions workflow calling cadence verify phase --changed on every pull request, plus prints (never executes) a gh api recipe 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 --json contract ({schemaVersion: 1, position, remainingTasks, blockedOn, legalMoves[]}) for agent orchestrators. Sourced from an extended nextAction() (packages/core/src/progress.ts), which now also computes ranked legalMoves[] alongside its existing {command, reason} shape — strictly additive; cadence progress and cadence quickstart are unchanged. Closes rec-20260721-002.

    Registers /cadence-next as the 15th Claude Code slash command and the matching Codex prompt command (both host adapters share the COMMAND_GUIDANCE catalog in @manehorizons/cadence-types).

    Also narrows cadence status --json and cadence quickstart --json's next field to {command, reason} explicitly — both were passing nextAction()'s full return through unnarrowed, so the new legalMoves[] array would otherwise have silently leaked into those two commands' existing public JSON contracts (mirrors the narrowing cadence progress already 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 findNearestCandidates helper (packages/core/src/intelligence/nearest-candidate.ts, extracted from cadence 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 from cadence recommend/cadence next's own ranking. cadence milestone propose gets 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 recommendation not-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 retro now distinguishes "no settled phases yet" from "phases scanned, zero friction found" instead of one ambiguous message for both.

    docs/concepts.md documents 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 a deferred milestone back to proposed so its claimed recommendations become eligible for re-clustering again. Previously applyTransition() had no path out of deferredclusterMilestones() treats any non-proposed milestone as a permanent survivor and permanently excludes its claimed recommendationIds, so a deferred milestone stayed stuck forever with no CLI recourse short of hand-editing milestones.json. reopen refuses loudly (exit 1, no state mutation) if the milestone isn't currently deferred (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.md artifact, sibling to the existing pre-DRAFT SPEC.md, for a phase that touches UI surfaces. cadence spec new --ui scaffolds it with a fixed shape — per-component Layout & Tokens and Precedent References nested under each ### <Component>, plus a whole-slice Responsive & Interaction section — so a design contract can be locked down before DRAFT tasks are written, closing rec-20260711-004.

    cadence spec approve runs a new convergent ui-spec-review gate after the existing spec-review gate, only when a sibling UI-SPEC is present: same nextConvergence primitive, its own <id>-UI-SPEC-REVIEW.json sidecar, its own unconditional ui-spec-review-unconverged anomaly, and its own independent --allow-ui-spec-review-failure bypass flag. cadence draft new seeds an approved UI-SPEC's content into a new ## UI Contract DRAFT section (bold-text rendering, no nested headings) between Acceptance Criteria and Tasks.

    No new loop position and no state.json schema change — opt-in purely by the UI-SPEC file's own presence, the same pattern the SPEC stage itself uses. The new uiSpecReview config key is wired into cadence config explain and cadence activate alongside the other six provider blocks.

Patch Changes

  • Updated dependencies [42deb4b]
  • Updated dependencies [6e774d5]
    • @manehorizons/cadence-types@1.50.0

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

v1.49.0

Choose a tag to compare

@github-actions github-actions released this 20 Jul 17:20
f444bd4

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 the SummaryZ schema, 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. Adds docs/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

v1.48.0

Choose a tag to compare

@github-actions github-actions released this 20 Jul 03:10
f0e26af

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-authored likelyFailureModes/hiddenDependencies entries now survive a later plain cadence milestone premortem <id> refresh alongside the freshly-derived deterministic entries, mirroring the guarantee outOfScope already 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 break MILESTONES.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's evidenceIds. Previously the only way to attach evidence after a recommendation's creation was a manual hand-edit of evidence.json and recommendations.json in lockstep — cadence intelligence reconcile does not help here, since deriveRecommendationLinks only re-derives assumptionIds/decisionIds from the assumption/decision ledgers, never evidenceIds from the evidence ledger, so a hand-added evidence entry silently would not show up in cadence recommendation show until evidenceIds was also hand-edited. The new command writes both ledger files atomically in one call, redacts secret-shaped substrings in the note the same way recommendation add --evidence does, and refuses cleanly (no ledger mutation) on an unknown recommendation id.
  • ac6722c: Fixes .cadence/state.json/STATE.md tracked-file cross-worktree merge conflicts (#177): cadence init now gitignores the four CADENCE-owned ephemeral paths (state.json, STATE.md, mcp-trust.json, intelligence/context/) by default, and cadence doctor/cadence doctor --fix gain a state-tracked check + untrack-state auto-repair to migrate existing repos (this repo included). The audit-trail value a tracked state.json used to carry incidentally now lives in a new stateAtSettle field on SUMMARY.json/SUMMARY.md, captured immediately before each settle resets the loop to IDLE. cadence doctor also diagnoses an unresolved git conflict in state.json with a field-by-field local/incoming diff instead of a bare JSON-parse error, and cadence doctor --fix --resolve-state-conflict=local|incoming writes the chosen side through the normal state-commit path. Any command that hits a corrupted state.json now prints a pointer to cadence doctor --fix instead of a bare error. docs/concepts.md, CLAUDE.md, and docs/reference/commands.md are 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, and cadence recommendation list: --filter-regex values were compiled directly with new 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, before new RegExp is 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 existing parseRegexFlags precedent. --filter-regex's --help text and docs/reference/commands.md are updated to document the length limit.
  • 9dd68f8: Fixes cadence onboard silently no-op'ing on a .cadence/ dir with a missing state.json (#177 fallout from phase 196's state.json/STATE.md gitignoring): a fresh git worktree or a fresh clone of a repo with .cadence/ already committed has no state.json yet, but onboard — 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.) throw NotInitializedError right after onboard reported success. onboard now bootstraps a fresh state.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 than package.json (which can disagree with the recorded project name in a monorepo), and prints a loud stderr notice when it does. An existing state.json is left completely untouched. cadence doctor's missing-state.json diagnostic now names cadence onboard as the fix instead of advice that no longer worked (cadence init correctly refuses on an already-.cadence/-committed repo). docs/reference/commands.md's onboard behavior section is updated to describe both the bootstrap and pass-through paths.
  • 2acd4c0: Fixes a bug (#248) where cadence recommendation add could reuse an already-issued recommendation ID once every recommendation created on a given day had been archived (e.g. shipped). nextRecommendationId only scanned the active recommendations array for the highest existing same-day sequence number, never the archived bucket — once the active array had no same-day entries left, the counter reset to 001 and 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-required settle gate that refuses cadence settle run when a task is marked DONE but its DRAFT - verify: line was empty or omitted — previously draft-parser.ts silently defaulted a missing line to '' and SUMMARY.md recorded a bare TN: DONE with zero evidence (#206). The gate fires in standard/complex tiers across strict/standard/auto profiles; quick-fix is 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.md and cadence explain gates are 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

v1.47.0

Choose a tag to compare

@github-actions github-actions released this 18 Jul 21:20
1923f6b

Package Changelog

Minor Changes

  • a786395: cadence dispatch plan gave 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 a recommendedIsolation value of 'worktree' or 'none': 'worktree' when the task declares one or more files: (it will mutate the working tree), 'none' when it declares none (read-only/no mutation expected). This is surfaced both as a new recommendedIsolation field in cadence dispatch plan --json's per-task output and as an advisory line in the rendered packet text itself — purely additive, no Task/Draft schema 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 via cadence build task <id> --status=... — the only thing scoping its behavior was a files: boundary. A real incident (2026-07-18) showed the gap: a dispatched fork agent overran its scoped task, ran cadence build/cadence settle and git commit directly against main four times, self-authorized without the orchestrator's review. Every rendered packet now includes a mandatory prohibition block forbidding state-mutating cadence subcommands (cadence build, cadence settle, etc.), git commit/git push, gh/network actions, and invoking AskUserQuestion — 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 run deterministically failing with StateConflictError whenever a host-cli verifier gate (whose subprocess can run for minutes) overlapped another subagent's SubagentStop hook — the hook's telemetry-only session.subagentSpawns += 1 was routed through the same revision-guarded SimpleStateBackend.commit() as structural writes, so every spawn bump invalidated any other command's in-flight snapshot and the failure never converged on retry (#234). StateBackend gains bumpSessionCounter(), a write path scoped to purely-informational session counters that never compares to or bumps the optimistic-concurrency revision field; 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

v1.46.0

Choose a tag to compare

@github-actions github-actions released this 18 Jul 02:17
3f8d7f0

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 (reusing cadence init's host-wire logic, now shared via init/host-wire.ts), reports the existing project's name and gate profile, and reports provider/API-key readiness — without re-scaffolding .cadence/config.json or state.json. Refuses cleanly with a pointer to cadence init when no .cadence/ is present. cadence init now also seeds a managed CONTRIBUTING.md block pointing new contributors at cadence 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 (default terminal), mirroring cadence intelligence stats's format-flag and exit-code conventions; never writes to state.json, STATE.md, or any phase artifact. @manehorizons/cadence-types gains additive RetroRollupZ, PhaseRetroEntryZ, RetroFrequencyEntryZ, and RetroFrequencyBucketsZ schemas (and their inferred types) backing the rollup shape. Fulfils rec-20260712-002.
  • 499558f: cadence doctor --fix now auto-remediates the handoff-retention check: when handoff.retain is unset and the .cadence/handoff/ SESSION-doc archive has grown past the existing warn threshold, --fix sets handoff.retain to the default (10) and immediately prunes the archive down to that budget, reusing the existing pruneHandoffDir/selectPrunable retention primitives and always preserving the active lastHandoff doc. 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 --fix cannot safely auto-decide.
  • eecc525: Wire a real hostCli builder into the 5 verifier families phase 165 left unwired: spec-review, plan-review, code-review, security-audit, and deep-verify (Verifier). Only per-task (phase 165 T7) had a working host-cli provider — every other family with provider: "host-cli" set in .cadence/config.json was silently falling back to mock (a deterministic placeholder, not real verification) regardless of config, since createVerifierFactory's generic host-cli dispatch only activates when a family supplies a hostCli() builder. Adds HostCliSpecReviewVerifier, HostCliPlanReviewVerifier, HostCliCodeReviewVerifier, HostCliSecurityAuditVerifier, and HostCliVerifier, each spawning the configured host CLI (claude/codex) headlessly via the existing hostCliJSON transport — same pattern as HostCliPerTaskVerifier, no new dependency. cadence doctor's verification-readiness claim for the verifier seam ("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 --activate flags: when their preconditions are met it wires the detected host with no prompt, seeds the 01-demo phase, and activates real verification when ANTHROPIC_API_KEY is 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. Bare cadence init with no flags is unchanged. Fulfils rec-20260709-001.

Patch Changes

  • 42dc58f: Fix --allow-auto-complex soft-cap overrides being invisible in SUMMARY.json and the real-time anomaly-notify transport. Settling a phase under the auto×complex soft cap with --allow-auto-complex now records a { gate: 'soft-cap', flag: '--allow-auto-complex', severity: 'warn' } entry in SUMMARY.json's gateBypasses, and cadence draft approve --allow-auto-complex now emits a new auto-complex-override AnomalyEvent through the anomaly-notify transport (mirroring coherence-warn) when the anomaly-notify gate is active. @manehorizons/cadence-types gains the additive 'auto-complex-override' value on AnomalyTypeZ.
  • 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

v1.45.0

Choose a tag to compare

@github-actions github-actions released this 15 Jul 21:20
b04534a

Package Changelog

Minor Changes

  • 90364bb: Add an MCP tool-trust envelope constraining cadence_draft_approve and cadence_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 a capabilityClass (READ_ONLY | LEDGER_WRITE | LOOP_WRITE | APPROVAL_BYPASS | SETTLE); the two APPROVAL_BYPASS tools now refuse (naming the failing check, before any state.json write) 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.json ledger (gitignored, not shared repo state like state.json). cadence_settle is classified SETTLE but deliberately left ungated this phase. See docs/concepts.md's new "MCP tool-trust envelope" section and docs/reference/commands.md's mcp trust entries 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) via gatherHandoffCandidates, and reports that worktree's live loop position — replacing N manual cadence status round-trips with one. Recommendations not yet converted to a phase, and converted phases with no matching worktree, are reported (as not-yet-converted/no-worktree-found) rather than dropped. Supports --json; refuses with exit 1 for an unknown milestone id, matching the existing accept/defer/close refusal 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 external AbortSignal (killing the child and rejecting with a new HostCliError reason 'aborted', distinct from the existing 'timeout') alongside its existing internal spawn-timeout timer. Verifier.verify and SecurityAuditVerifier.verify both gain the same optional second parameter — LocalVerifier/LocalSecurityAuditVerifier forward signal into the underlying fetch/localChatJSON call, AnthropicSecurityAuditVerifier forwards signal into the Anthropic SDK's request options, and MockVerifier/MockSecurityAuditVerifier accept-and-ignore it. The security-audit gate 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 to packages/core/src/gates + security-audit.ts's verifier hierarchy per rec-20260712-010; the same pattern is left for a future phase to apply to PerTaskVerifier/CodeReviewVerifier/PlanReviewVerifier/SpecReviewVerifier.
  • 462f239: Harden the host-cli verifier provider against three risks: invisible consumption of the host CLI's own subscription/usage quota during verification calls, an unguarded self-invocation path when cadence itself is already running inside the same host CLI it would spawn, and a subprocess hang when the spawned process never exits. hostCliJSON now emits a one-time-per-process stderr notice on the first real spawn (never on provider selection alone); refuses to spawn — falling back to mock via the existing per-call fallback path — when the claude family's session env var (CLAUDECODE=1) indicates cadence is already running inside a headless claude session (codex has no reliable documented equivalent and is left unguarded); and bounds the spawn with a configurable CADENCE_HOST_CLI_TIMEOUT_MS timeout (default 3 minutes) that kills a hung subprocess and rejects with a new HostCliError(reason: 'timeout') instead of hanging forever. See docs/providers.md's host-cli section for full operator-facing detail, including the consequence that host-cli calls always fall back to mock when cadence runs 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 via addRecommendation's evidenceSummary) and security-audit gate Finding.message (both SUMMARY.securityAudit and the per-critical stderr log) now pass through a new redactSecrets utility before being written, replacing AWS access keys, GitHub tokens, bearer/basic Authorization header values, JWT-shaped strings, PEM private-key blocks, and generic key=/token=/password=/secret= assignments with [REDACTED]. The four intelligence ledger JSON files (recommendations.json, evidence.json, assumptions.json, decisions.json) are now also written with 0o600 (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

v1.44.1

Choose a tag to compare

@github-actions github-actions released this 13 Jul 01:27
7430b28

Package Changelog

Patch Changes

  • Fix a gate implementation's thrown exception escaping uncaught out of runSettleGates to settle.ts's outer catch, which printed to stderr and exited 1 with no SUMMARY written — security-audit was previously the sole gate normalizing its own throws into a refuse outcome. The gate invocation in runSettleGates is 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 persists SUMMARY.json/SUMMARY.md and leaves loop state untouched. Closes rec-20260712-007.
  • e38d86a: Add optimistic concurrency to SimpleStateBackend.commit() to prevent lost updates when two cadence state writers (CLI commands, hooks, or the MCP server) race on .cadence/state.json in 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. CadenceState gains a revision: number field (additive, .default(0), back-compat with pre-existing state.json files). commit() now compares the current on-disk revision to the caller's in-memory state.revision before writing: a match bumps it in place and writes as before; a mismatch refuses with a new StateConflictError (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 existing state.json) skips the check entirely. The in-place revision bump means a caller issuing several sequential commit() 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 clean DONE, and any code-review/security-audit/boundary-scan findings — is synthesized purely from the SUMMARY data already assembled and written as <draftId>-RETRO.json/.md alongside SUMMARY.json/.md (a clean settle writes a "No friction detected this settle." form). @manehorizons/cadence-types gains an additive RetroDigest/RetroDigestZ schema and a retro: { enabled, offerGithubIssue } config block (both default true, same shape convention as the existing recommendations block). When the digest is non-empty and the run is interactive (a real TTY, or the CADENCE_PROMPTER_SCRIPT test seam), settle also offers to file a GitHub issue for it via gh — 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 it needs-triage in 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 in settle.ts and handoff/run-resume.ts) was consolidated into one shared createDefaultPrompter() in verify/prompter.ts as 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 gates provenance and a refused settle run writing no SUMMARY at all — previously the only trace of a refusal was an ephemeral stderr line. GateProvenanceZ.status gains a 'refused' value plus an optional reason string (additive, back-compat with pre-existing ran/skipped records); 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 attach reason matching their stderr text on refusal, and runSettleGates pushes the refusing gate's entry onto gates before halting. A refused cadence settle run now persists SUMMARY.{json,md} (populated gates through the refusing entry, real taskResults, empty acResults/decisions/deferred) without transitioning loopPosition/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

v1.44.0

Choose a tag to compare

@github-actions github-actions released this 11 Jul 20:45
104c119

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.coverageProfiles lets 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-coverage gate (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 --explain diagnostic. cadence init's default verification.testGlobs for rust now also includes src/**/*.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).

Patch Changes

  • a5b21ec: Fix cadence init defaulting verification.coverageMode to 'assertion' for every project regardless of language, which made the test-coverage gate permanently unsatisfiable for non-JS/TS projects (the assertion-mode span-finder only recognizes JS/TS it()/test() syntax).

    • cadence init now 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 defaults coverageMode to '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.json files are never rewritten.
    • Default verification.testGlobs are now language-aware too, so mention-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-coverage gate'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 asserting it()/test() block — each with its own suggested fix.
    • cadence doctor (and the MCP doctor tool) now warns when coverageMode: 'assertion' is paired with a detected project language that has no assertion-mode parsing support yet, suggesting cadence 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-coverage gate in assertion coverage mode wrongly treating an AC whose only linked test sits inside a test.skip/.todo/.failing block as fully covered, even when the block contains an intact assertion. Previously cadence settle run --auto would 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 unrelated coverageMode switch.

    findTestSpans now flags skip/todo/failing openers as non-asserting spans (only/concurrent are unaffected, since those execute normally); scanTestCoverage propagates this through a new skipped flag on each test reference, and a new skippedOnlyLinkedAcs export is mutually exclusive with the existing weaklyLinkedAcs — 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

v1.43.0

Choose a tag to compare

@github-actions github-actions released this 11 Jul 01:06
1590456

Package Changelog

Minor Changes

  • Enable cadence init to 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-level AGENTS.md guidance, and flows through the
      same init path as Claude Code — previously Codex setup only installed
      adapter hooks/prompts and skipped AGENTS.md generation.
    • cadence doctor gained Codex readiness checks (hooks, prompts,
      AGENTS.md, global command availability), each with an opt-in doctor --fix remediation.
    • Codex/quickstart/CLI docs point first-time users at cadence init --host codex instead 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 resume now runs a best-effort origin-freshness probe before
      replaying a doc (config resume.remoteCheck, default true; --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 resume and cadence handoff --check (new) both detect
      scaffolded <!-- … FILL IN … --> sections left unfilled by a prior
      session and flag them — resume as a warning, handoff --check as an
      exit-3 completion gate.
    • cadence handoff --no-fetch skips the pre-facts git fetch for a fully
      offline write; git-facts records whether the fetch actually ran.
    • The Claude Code /cadence-handoff and /cadence-resume slash-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-authenticated claude/codex CLI in headless mode instead of requiring a separate ANTHROPIC_API_KEY.

    • New provider value 'host-cli' on every provider config slice (verifier, perTaskVerifier, codeReview, planReview, securityAudit, specReview), plus cadence activate --provider host-cli and cadence settle run --verifier host-cli. Binary discovery defaults to claude on PATH, overridable via CADENCE_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 mock with 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 activate report host-cli readiness 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. See docs/providers.md for the full picture, including a known no-spawn-timeout gap.
    • The JSON-extraction + schema-repair-retry logic previously private to the local provider is now a shared, transport-agnostic module (json-repair.ts) reused by both local and host-cli.
  • 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 .env file 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 doctor unless manually exported.
    • cadence activate's live provider check is no longer coincidentally
      skippable — when a key is discovered and the provider isn't mock, the
      smoke test runs and its outcome (not mere key presence) gates whether
      activation is reported as successful. --no-check remains 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 — including cadence mcp serve --repo <path>, where
      the server process's own working directory can differ from the repo being
      operated on. A teammate who never ran cadence activate locally, but
      whose key is discoverable and whose repo already commits a real provider
      choice, now gets real verification instead of a silent mock fallback.

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

v1.42.0

Choose a tag to compare

@github-actions github-actions released this 07 Jul 04:26
26d347c

Package Changelog

Minor Changes

  • Add boundaryEnforcement: 'warn' | 'block' (default warn, back-compat), overridable per-phase via DRAFT frontmatter. In block mode, handlePreToolEdit refuses 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 zero files: in total.
  • Add a boundary-scan settle gate — closes the blind spot edit-time boundaryEnforcement: '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 when boundaryEnforcement resolves to block — bypassable via --force/--allow-boundary-scan-failure unless 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 new redundantWorkEnforcement: 'off' | 'warn' | 'block' config (default warn, DRAFT-frontmatter overridable), plus a SubagentStart baseline snapshot + advisory task-board nudge and a SubagentStop safety 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 over depends: edges and files:-overlap prerequisite edges, plus cycle/unknown-dependency detection), and a new /cadence-dispatch Claude Code slash command that drives the host agent through a parallel Task-tool dispatch loop over the computed waves. Task gains an optional depends: string[] DRAFT.md field.

Patch Changes

  • Fix parseSpecMd/parseDraftMd silently 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