Skip to content

Releases: Gentleman-Programming/gentle-ai

v2.4.0 β€” Review Waits To Be Asked

Choose a tag to compare

@github-actions github-actions released this 17 Aug 18:40
Immutable release. Only release title and notes can be modified.
301fb2a

v2.4.0 β€” Review Waits To Be Asked

v2.4.0 is main at 301fb2ad, not a promoted release candidate. The v2.4.0-rc.1 through v2.4.0-rc.8 series measured this work as it went; the stable is the state of main after that measurement, with 430 non-merge commits since v2.3.0 and 200 of them scoped to review.

Provenance: this release contains the 301fb2ad bytes. ci.yml and the Windows Full Suite are both green on that exact commit.

Breaking: receipt-driven development is now opt-in

The default resolution of the review kill switch flips from on to off. An install nobody configured no longer starts reviewing on its own.

If you explicitly enabled review, nothing changes. An explicit global on is read back untouched across the upgrade, and a clone-local override still wins over it. Only an installation that never expressed an opinion resolves differently, and it resolves to off.

To turn review on:

gentle-ai review mode enable --scope global

gentle-ai review mode status is read-only and reports the effective mode and the source that decided it.

Delivery under the new default falls back to ordinary repository policy: hooks, tests, CI. Nothing is silently approved.

Upgrade now

brew upgrade gentle-ai

Run gentle-ai sync after upgrading. Replacing the binary does not refresh the managed runtime assets already installed for your agents.

What changed

The review lifecycle stopped getting stuck

  • A candidate with more than 32 changed paths is reviewable. The entry cap that refused it reported itself under the byte-budget reason code, so the advice it gave β€” split the candidate β€” could never work.
  • Authority repair no longer dead-ends past 256 lineages; a truncated preflight names gentle-ai review inspect-authority as its way forward instead of terminating.
  • A receipt denial names your candidate's own situation instead of enumerating unrelated lineages.
  • gentle-ai review store-reset clears a clone's review store and reports exactly what it removed and what it spared. Preview is the default and --confirm is required. The kill-switch mirror, SDD runtime state, defect reports, review artifacts and incidents are preserved regardless.
  • Pre-push symbolic selectors survive base-advance validation, and empty unborn staged assessments are classified instead of failing.

Provider runtimes reach the reviewer

  • Pi is a registered host-mediated runtime identity, with the Go-issued provider task materialized for its host relay, including refuter and validator roles.
  • OpenCode relays provider contracts through live transport.
  • Provider roles route through the native lifecycle, and the provider contract bundle is published with the release.
  • The targeted validator receives the inspection recipe for the frozen candidate, and captured validator slots finalize generically.

Windows

  • The internal/cli shards are sized from measured cost rather than test-name first letter. cli-d-q was exceeding the 1800s timeout at 1818s; the worst shard now projects to about 1020s.
  • RAR ownership, path canonicalization, byte-range locking and case sensitivity fixes brought the Windows suite green.

Everything else

  • Managed background-subagent policy for the Pi runtime, and background subagent orchestration for OpenCode across install, sync and TUI.
  • Durable effect markers, repository-context recovery and reconciliation.
  • Dynamic custom OpenCode agent discovery with model assignment; Codex installer models discovered from the CLI.
  • SDD asks when the attempt budget is exhausted instead of dead-ending, and the post-review verify report is attested through native settlement.

Known issues in these exact bytes

These describe release scope, not the current state of every linked issue.

  • Self-service recovery records the maintainer git identity as the authorizing actor and ignores --actor (#3401).
  • The store-global authority lock's hold time grows with lineage count and begins failing at scale (#3372); lock contention is reported as authority corruption in three places (#3373).
  • A candidate with a single path over 4 MiB starts, then loops on a refusal that can never clear (#3389).
  • Stop transitions emit a bare reason_code, leaving consumers to invent their own continuations (#3384).
  • The inconclusive-validation bound does not apply when the validator slot was never occupied (#3393).
  • A correction that fully reverts one frozen-candidate file breaks negotiated finalize (#3321).
  • Lineages accumulate with no retention policy (#1656). store-reset is the exit that ships here; the design question is open, and #3417 proposes making the review atomic so there is nothing to retain.

Install and integrity

For an existing Homebrew installation, use the upgrade command above. For a first Homebrew install:

brew install gentleman-programming/tap/gentle-ai

If Homebrew is not your path, install the tagged Go module and then refresh the managed assets:

go install github.com/gentleman-programming/gentle-ai/v2/cmd/gentle-ai@v2.4.0

The release includes four Darwin/Linux .tar.gz archives: darwin_amd64, darwin_arm64, linux_amd64, and linux_arm64. checksums.txt contains their SHA-256 digests, and checksums.txt.minisig is the detached Minisign signature for that manifest. Verify the signed checksum manifest before using a raw archive.

The Windows stable binary is intentionally omitted under the existing Authenticode policy.

Community evidence

Eight release candidates shaped this release, and most of what got fixed came from people reporting real runs in the runtime they actually use. The default changing to opt-in came from that feedback too. Keep reporting: evidence is how the next release gets better.

v2.4.0-rc.8 β€” What STATUS advertises, the runtime executes

Choose a tag to compare

@Alan-TheGentleman Alan-TheGentleman released this 14 Aug 14:54
Immutable release. Only release title and notes can be modified.
b002e0e

What to test

Start with the paths this candidate fixed against written reproductions rather than real use:

  • Recover a review after a rebase. Approve a review, commit the candidate, rebase it across an unrelated parent advance, and follow exactly what negotiated STATUS tells you. STATUS with an explicit lineage that owns no authority now advertises the decision START will actually make instead of a fresh start that START then reinterprets. The staged-predecessor RECOVER leg of the same report is pinned by a guarded property test but was not reproducible on main; if you can make STATUS render a RECOVER that its own preflight refuses, that transcript is the most valuable thing you can send.
  • Correction-only delivery after a post-merge review. Review an already-merged candidate, let it find a real defect, apply the one bounded correction, and publish only the correction as a PR over the merged base. pre-pr now recognizes that receipt-derived projection; any other base or an unreviewed commit on top must still deny.
  • OpenCode background subagents. On OpenCode 1.15.11 or newer, enable --opencode-background-subagents=on at install or sync, restart through the managed launcher, and watch that only independent read-only work runs in the background while writers, RDD actors, and Judgment Day stay foreground. Turning it off must remove only Gentle-owned launchers.
  • The provider contract bundle. This candidate ships gentle-ai-review-provider-contract-1.0.0.tar.gz as a release asset. Verify it from the tagged source with go run ./internal/providercontractbundlecmd verify --archive <bundle> and inspect its inventory with tar -tzf <bundle>.
  • Windows, all of it. This candidate is the first whose full review-transaction surface actually executed on Windows before shipping. If you run Windows, ordinary negotiated reviews, captures, and finalizes are the test.

The one change whose argument is verified in tests and unproven in the field: the unified provider transport. Every reviewer, refuter, and validator invocation now crosses one generic Go boundary with immutable role slots β€” exercised end to end in CI against real OpenCode, and never yet by a fleet of real operators. Finding a provider flow it mishandles is the most useful thing this candidate can learn.

A known risk ships unresolved and named: under full-shard Windows load, the authority-lock waiter can time out a healthy queue of slow publishers (#3239). The fix exists, is property-tested on Linux, and is deliberately held out of this candidate until its own Windows execution is clean.

What rc.7 taught us

rc.7's field reports were convergence reports: STATUS advertising transitions that RECOVER and START then refused or reinterpreted, and a Windows suite that had never actually executed the surfaces it claimed to cover. This candidate stays within the same line as rc.7 β€” no public Go API change, fail-closed admission everywhere β€” and spends its weight making the advertised transition and the executed transition the same decision, and making Windows execution real instead of assumed.

One provider transport under the Go contract

Provider reviewer, refuter, and validator invocations ran through per-client shims that each interpreted the contract on their own. They now route through one generic invocation boundary with provider roles persisted in immutable slots, conformance hardened at admission, and the review provider contract published as a versioned release asset (1.0.0) that downstream clients verify instead of re-deriving.

Durable effects and the repository context that survives processes

A committed repository-context event used to live only as long as the process that created it. The compact authority now records effect intents at START, publishes durable markers with monotonic states, and reconciles the committed context across fresh STATUS, START, and recovery processes β€” replaying idempotently instead of re-deriving. The record revision stays a pure function of state, so every existing re-deriver keeps verifying lineages that carry intents.

STATUS, START, and RECOVER answer from one decision

An explicit lineage that owned no authority made STATUS classify the live target as fresh while START's discovery resolved the byte-identical approved authority and answered reuse-receipt on another lineage. The classification now falls back to unrestricted discovery when the requested lineage owns nothing, so the rendered transition replays against the same decision. The correction-only publication over an already-merged candidate β€” approved by the receipt, denied by the gate since v2.2.2 β€” is now recognized as the one receipt-derived pair it is, with everything else still denied.

Windows execution became real

Six review-transaction surfaces reached main having only ever compiled on Windows: fixtures faked the runtime POSIX-only, asserted permissions Windows cannot represent, read locator artifacts with the strict private-RAR bar, and resolved $HOME where Windows resolves %USERPROFILE%. All are fixed, the RAR effects family now executes in the PR-side Windows Runtime job before merge, and the diagnostics run that proved the production engines correct on Windows is part of the record. The one Windows red left standing is the load-dependent authority-lock contention, tracked and named rather than papered over.

Managed background subagents for OpenCode

OpenCode gains an auto|on|off background-subagent policy across install, sync, environment, and TUI, delivered through a Gentle-owned launcher with an ownership marker, a reversible activation transaction, and rollback that participates in the install pipeline's compensation. The orchestrator addendum keeps dependency-bearing, decision-bearing, and review-bearing work foreground, and degrades to foreground wherever the runtime cannot prove support.

Also in this candidate

The AI contribution policy landed as documentation-only governance with proportional disclosure and no attribution to tools. Issue-creation authority collapsed to the embedded skill that discovers labels instead of promising them. The explore agent gained the read-only CodeGraph tool with the wildcard explicitly forbidden. Codex model discovery went asynchronous with a curated fallback. Persona output-style resources derive from one plan. Defect reporting routes by the installed build's evidence channel and never recommends switching channels. The journey corpus is manifest-derived, ending the counter collisions that turned main red when two green PRs met.

Numbers

589 issues open now against roughly 581 at rc.7: 19 opened and 11 closed in the interval. Inflow exceeded outflow; this candidate does not call that progress.

Install

go install github.com/gentleman-programming/gentle-ai/v2/cmd/gentle-ai@v2.4.0-rc.8

Or the platform binaries below: linux_amd64, linux_arm64, darwin_amd64, darwin_arm64, windows_amd64.exe, plus gentle-ai-review-provider-contract-1.0.0.tar.gz. SHA256SUMS.txt covers all six payload artifacts.

v2.4.0-rc.7 β€” Truthful exits, exact authority

Choose a tag to compare

@Alan-TheGentleman Alan-TheGentleman released this 12 Aug 16:13
Immutable release. Only release title and notes can be modified.
72cf613

What to test

  • In a root-commit repository with committed-only review scope, ask STATUS with the root commit as --base-ref. It must stop with the empty-base-diff bootstrap result before offering START; it must not create a lineage or send the operator into a preflight rejection loop (#3102).
  • Create a candidate whose frozen reviewer evidence exceeds the deterministic context limit, start its review, then ask STATUS. It must terminate with lens_context_budget_exceeded, create no retry artifact or receipt mutation, and tell the operator to reduce scope or start a new review (#2773).
  • Leave an immutable reviewer slot occupied, then ask for its next action. The result must say the slot is occupied and direct the operator to negotiated STATUS. It must not retry context collection or recommend disposing of or preserving the slot as a workaround (#3103).
  • Start with a historical clone-local review-mode authority record and make its first exact-revision mutation. The record must migrate while preserving stale-CAS behavior, the global-off kill switch, and the legacy forensic bytes (#3061, #2831).
  • On Windows, run the legacy-migration fixture and confirm the secure DACL path succeeds. This is a regression check for #3036.
  • Run review status on Git installations with different merge-tree capability shapes. Capability detection must select the supported form and fail clearly when no supported form exists (#2927).

The riskiest field-unproven change is migration of a real historical legacy clone-local authority record on a tester machine. Tests, race coverage, and the Windows secure-DACL proof establish the mechanics; published field use is the measurement.

What the previous candidate taught us

v2.4.0-rc.6 taught us that green source checks were not sufficient. Exact current builds found gaps in truthful continuation, immutable-slot classification, and legacy-root handling. This candidate closes those gaps while staying within the 2.4.0 line. It does not widen the public Go API.

Truthful exits

An empty committed base diff previously reached a status path that could still offer START even though START had nothing valid to inspect. STATUS now stops at that boundary and names the bootstrap condition. An oversized immutable reviewer context likewise now ends deterministically instead of offering work that cannot complete, without consuming a retry, artifact, or receipt transition.

Exact authority

Occupied reviewer slots are classified as occupied state rather than as context failures, so the operator is routed to the negotiated status that owns the transition. Historical clone-local authority records migrate at their first exact-revision mutation, preserving their stale-CAS protection, global-off behavior, and original forensic bytes. The Windows fixture now exercises that migration through the secure DACL path.

Portable capability handling

Review status now handles the Git merge-tree capability shapes identified in #2927 rather than assuming one invocation is universally available. The candidate also carries the corresponding test and benchmark coverage for the new truthful boundaries.

Also in this candidate

The range includes hardening across review state, command-line continuations, benchmark coverage, Windows filesystem behavior, updater argument handling, runtime configuration, and TUI model selection. These are fixes and tests around existing behavior, not a claim of broader public API surface.

Install

go install github.com/gentleman-programming/gentle-ai/v2/cmd/gentle-ai@v2.4.0-rc.7

Binary assets: gentle-ai_2.4.0-rc.7_linux_amd64, gentle-ai_2.4.0-rc.7_linux_arm64, gentle-ai_2.4.0-rc.7_darwin_amd64, gentle-ai_2.4.0-rc.7_darwin_arm64, and gentle-ai_2.4.0-rc.7_windows_amd64.exe; verify the selected binary with SHA256SUMS.txt.

v2.4.0-rc.6 β€” Review waits its turn

Choose a tag to compare

@Alan-TheGentleman Alan-TheGentleman released this 11 Aug 10:28
Immutable release. Only release title and notes can be modified.
e612ef3

HOTFIX over rc.4

v2.4.0-rc.4 was tagged and published but never carried binaries, so this candidate supersedes it before it reached anyone. v2.4.0-rc.5 was burned by a tooling mistake on our side and never published; nothing was released under it. Two defects landed after it, both in the path this candidate asks you to exercise.

A filesystem root is no longer answered as if it were a project. sdd-status --cwd / returned a successful, empty, entirely plausible status: changeName: null, artifactStore: openspec, planningHome: "/openspec". A phase-failure continuation that resolved its working directory to the drive root therefore read as "SDD lost my project" rather than "that command was pointed at the wrong directory". It now refuses and names the runnable continuation.

Engram-backed changes are closed by their archive report. A change that had ever persisted an artifact was reported active forever, because the two stores archive differently and only one leaves a trace the resolver reads: OpenSpec moves the directory out of changes/, Engram moves nothing. Archive already wrote sdd/{change}/archive-report and the title pattern did not recognize it, so the one artifact proving a change was finished was the one never read. Measured on a real store, thirty changes for a single project were reported active, seven of them archived weeks earlier. Naming an archived change still resolves it; only discovery excludes it.

Everything below is unchanged from rc.4.

What to test

Almost everything below was fixed against a written reproduction, not against real use. The paths that most need a human are in the SDD attempt lifecycle:

  • Run a work unit end to end: sdd-attempt acquire, do the work, sdd-attempt settle. Before acquiring, pass the work-unit scope to sdd-attempt status and check it tells you the same thing acquire will.
  • Fail a verification, then correct it. Confirm the correction settles and that nothing demands paperwork you were never told about while the attempt was still open.
  • Spend an objective's attempts until the budget runs out. It should ask you whether to open a fresh one, with a command that runs as printed.
  • Do the same with receipt-driven review disabled at clone scope, and confirm it stays out of the way completely.

The one change to watch. A review binding no longer blocks a passing implementation attempt from closing. The argument is that the delivery gates re-derive their verdict from the candidate actually being delivered, so an unreviewed candidate is still refused at commit, push, PR and release. That argument is verified in tests and unproven in the field. If an unreviewed candidate reaches delivery, that is this change, and it is the single most useful thing this candidate can learn.

What the previous candidates taught us

v2.4.0-rc.1 made refusals name their exit. v2.4.0-rc.3 bound the proof to the candidate the operator is actually delivering. This candidate turns to the surface those two never covered: the SDD attempt ledger, where a refusal could be correct, name a real exit, and still leave the operator with nowhere to go.

The changes remain within the 2.4.0 line and do not widen the public Go API. One fail-closed rule was deliberately removed rather than tightened, and the section below says which and why; every other admission that held in rc.3 still holds.

Review acts after implementation, not during it

Receipt-driven review runs on the finished result: you implement, verify, and only then is review offered, freezing what is already done. Two rules disagreed with that.

A passing implementation attempt was refused whenever the review binding covered the bytes from before the attempt β€” which it always does, because changing the candidate is what an attempt is for. That is review deciding whether implementation may finish. The one named exit demanded an approved review of the corrected candidate, and producing it opened a fresh correction budget and a fresh reviewer that the contract forbids after independent verification. Four doors, all locked.

The kill switch was also a half-measure. Unmanaged remediation required review to be off and no binding to exist, so a binding created before the operator turned review off kept blocking corrections. While review is off it does not exist, and a leftover binding is an implication.

Neither change weakens delivery. The delivery gates re-derive their verdict from the candidate actually being delivered, so an unreviewed candidate is still refused there, after SDD finishes. The binding stays recorded: review stops deciding, it does not stop being tracked.

The attempt ledger stops contradicting itself

Status reported next_action: begin while acquire blocked on the same request, because Begin evaluated its repository-side preconditions inside its mutation closure where no read-only surface could reach them. Both halves now run through one predicate, so the two surfaces cannot disagree.

Three refusals compared two values and disclosed neither. They now print both sides: the approved tree against the charged tree with a git diff between them, the bound revision against the current one, and the failure a correction names against the one the chain actually holds unremediated. One of them was telling operators their input was wrong when it was correct and merely obsolete.

An exhausted budget used to end the conversation in prose naming a reset the operator had to assemble from six flags. It now asks, with the accounting in front of them and a grant that runs verbatim. Attempts that never ran the work are named as such, because an exhausted budget means something different when none of it was spent on the candidate.

Negotiated transitions come from one authority

Canonical STATUS target and recovery projection moved into reviewtransaction, so CLI adapters render a decision instead of reconstructing it. Staged base-diff requests are canonicalized before target identity is derived, making the START that STATUS emits executable against the same target.

Effective review mode is resolved once, before STATUS publishes either eligibility or a transition, so a disabled clone stops being offered a review it cannot start. An unborn workspace reaches the explicit untracked-selection transition instead of a generic retry. An approved committed base-diff receipt survives a conflict-free local parent merge that carries the identical reviewed patch, reusing the existing compatibility proof rather than minting a new lineage.

The defect reporter stops filing other projects' bugs

The automated handoff asked whether the workflow appeared blocked by a Gentle AI defect, and from the operator's seat everything that blocks them appears to qualify: a model refusing an oversized image, a client runtime needing its session restarted, a sub-agent returning nothing.

The test is now what produced the failure, not what the work was doing when it happened. A Gentle AI invocation producing it is the whole gate; a Gentle AI workflow merely hosting one is not, because the client runtime carries out the work. Everything else is silent β€” no report, no naming the component believed responsible, no suggesting where else to file it.

Also in this candidate

OpenCode plugin upgrades verify the installed manifest instead of assuming the requested version materialized. Claude workspace MCP servers are written to .mcp.json, the file Claude Code actually reads for project scope, and the inert settings.json block is cleaned up conservatively. The selected persona syncs to Pi, distinguishing an omitted legacy field from an explicit empty one. Historical compact dispositions, retired snapshot identities, frozen lineage resume, and atomic reviewer-slot reads are all tightened.

Install

go install github.com/gentleman-programming/gentle-ai/v2/cmd/gentle-ai@v2.4.0-rc.6

Or download a binary below and verify it against SHA256SUMS.txt.

v2.4.0-rc.4 β€” Review waits its turn

Choose a tag to compare

@Alan-TheGentleman Alan-TheGentleman released this 11 Aug 08:52
Immutable release. Only release title and notes can be modified.
69ac5a4

What to test

Almost everything below was fixed against a written reproduction, not against real use. The paths that most need a human are in the SDD attempt lifecycle:

  • Run a work unit end to end: sdd-attempt acquire, do the work, sdd-attempt settle. Before acquiring, pass the work-unit scope to sdd-attempt status and check it tells you the same thing acquire will.
  • Fail a verification, then correct it. Confirm the correction settles and that nothing demands paperwork you were never told about while the attempt was still open.
  • Spend an objective's attempts until the budget runs out. It should ask you whether to open a fresh one, with a command that runs as printed.
  • Do the same with receipt-driven review disabled at clone scope, and confirm it stays out of the way completely.

The one change to watch. A review binding no longer blocks a passing implementation attempt from closing. The argument is that the delivery gates re-derive their verdict from the candidate actually being delivered, so an unreviewed candidate is still refused at commit, push, PR and release. That argument is verified in tests and unproven in the field. If an unreviewed candidate reaches delivery, that is this change, and it is the single most useful thing this candidate can learn.

What the previous candidates taught us

v2.4.0-rc.1 made refusals name their exit. v2.4.0-rc.3 bound the proof to the candidate the operator is actually delivering. This candidate turns to the surface those two never covered: the SDD attempt ledger, where a refusal could be correct, name a real exit, and still leave the operator with nowhere to go.

The changes remain within the 2.4.0 line and do not widen the public Go API. One fail-closed rule was deliberately removed rather than tightened, and the section below says which and why; every other admission that held in rc.3 still holds.

Review acts after implementation, not during it

Receipt-driven review runs on the finished result: you implement, verify, and only then is review offered, freezing what is already done. Two rules disagreed with that.

A passing implementation attempt was refused whenever the review binding covered the bytes from before the attempt β€” which it always does, because changing the candidate is what an attempt is for. That is review deciding whether implementation may finish. The one named exit demanded an approved review of the corrected candidate, and producing it opened a fresh correction budget and a fresh reviewer that the contract forbids after independent verification. Four doors, all locked.

The kill switch was also a half-measure. Unmanaged remediation required review to be off and no binding to exist, so a binding created before the operator turned review off kept blocking corrections. While review is off it does not exist, and a leftover binding is an implication.

Neither change weakens delivery. The delivery gates re-derive their verdict from the candidate actually being delivered, so an unreviewed candidate is still refused there, after SDD finishes. The binding stays recorded: review stops deciding, it does not stop being tracked.

The attempt ledger stops contradicting itself

Status reported next_action: begin while acquire blocked on the same request, because Begin evaluated its repository-side preconditions inside its mutation closure where no read-only surface could reach them. Both halves now run through one predicate, so the two surfaces cannot disagree.

Three refusals compared two values and disclosed neither. They now print both sides: the approved tree against the charged tree with a git diff between them, the bound revision against the current one, and the failure a correction names against the one the chain actually holds unremediated. One of them was telling operators their input was wrong when it was correct and merely obsolete.

An exhausted budget used to end the conversation in prose naming a reset the operator had to assemble from six flags. It now asks, with the accounting in front of them and a grant that runs verbatim. Attempts that never ran the work are named as such, because an exhausted budget means something different when none of it was spent on the candidate.

Negotiated transitions come from one authority

Canonical STATUS target and recovery projection moved into reviewtransaction, so CLI adapters render a decision instead of reconstructing it. Staged base-diff requests are canonicalized before target identity is derived, making the START that STATUS emits executable against the same target.

Effective review mode is resolved once, before STATUS publishes either eligibility or a transition, so a disabled clone stops being offered a review it cannot start. An unborn workspace reaches the explicit untracked-selection transition instead of a generic retry. An approved committed base-diff receipt survives a conflict-free local parent merge that carries the identical reviewed patch, reusing the existing compatibility proof rather than minting a new lineage.

The defect reporter stops filing other projects' bugs

The automated handoff asked whether the workflow appeared blocked by a Gentle AI defect, and from the operator's seat everything that blocks them appears to qualify: a model refusing an oversized image, a client runtime needing its session restarted, a sub-agent returning nothing.

The test is now what produced the failure, not what the work was doing when it happened. A Gentle AI invocation producing it is the whole gate; a Gentle AI workflow merely hosting one is not, because the client runtime carries out the work. Everything else is silent β€” no report, no naming the component believed responsible, no suggesting where else to file it.

Also in this candidate

OpenCode plugin upgrades verify the installed manifest instead of assuming the requested version materialized. Claude workspace MCP servers are written to .mcp.json, the file Claude Code actually reads for project scope, and the inert settings.json block is cleaned up conservatively. The selected persona syncs to Pi, distinguishing an omitted legacy field from an explicit empty one. Historical compact dispositions, retired snapshot identities, frozen lineage resume, and atomic reviewer-slot reads are all tightened.

Install

go install github.com/gentleman-programming/gentle-ai/v2/cmd/gentle-ai@v2.4.0-rc.4

Or download a binary below and verify it against SHA256SUMS.txt.

v2.4.0-rc.3 β€” Proof follows the candidate

Choose a tag to compare

@Alan-TheGentleman Alan-TheGentleman released this 09 Aug 23:47

What the previous candidates taught us

v2.4.0-rc.1 made refusals actionable. This candidate tightens the other half of that contract: the proof must stay bound to the candidate the operator is actually trying to deliver, even when the repository moves underneath it.

The changes remain within the 2.4.0 line. They harden negotiated review, delivery and recovery behavior without widening the public Go API or weakening fail-closed admission.

Pre-PR review now follows moving bases

A pre-PR review used to bind the candidate to the base tip. That made an unrelated base advance invalidate an otherwise unchanged candidate, and it left room for a reviewed diff to diverge from the merge result.

Pre-PR identity now binds to the merge base. Compatible base advances preserve the reviewed candidate, while malformed or unavailable proofs still fail closed. The bench corpus exercises both the moving-base transition and its typed denial diagnostics.

Reviewed subsets can ship safely

Delivery no longer requires the staged tree to be byte-for-byte identical to the full reviewed tree when the staged candidate is a monotonic subset of it. The proof checks the actual merge result and rejects unreviewed merge resolution, so narrowing a reviewed change is allowed without admitting new bytes.

Recovery exits are executable

Consecutive SDD rescope recovery now keeps its continuation delimiter-safe and bound to the exact published RC fixture. Compact-budget and post-remediation paths preserve their native contracts instead of sending the operator toward an impossible transition.

Provider defects no longer force reporting

The provider-defect handoff now offers three explicit outcomes: report and continue, continue without reporting, or stop. Both continuation paths reuse the provider-captured candidate-scoped decline invocation exactly once, validate its result and target, then re-enter through negotiated STATUS. Continuing never disables receipt-driven development.

Windows no longer needs a PowerShell ACL module

Managed-file permission handling on Windows depended on the optional PowerShell ACL module being present. Where it was absent the check failed for reasons unrelated to the property under test. Permissions are now asserted without that dependency, and ACL inheritance provenance is ignored rather than compared, because it varies by host policy and never described the guarantee. Review snapshot repository templates are stabilized alongside it.

Also in this candidate

The minimum TUI layout keeps its selected action visible on short viewports, atomic one-line corrections are admitted, transient empty Engram PID files get a bounded retry, linked-worktree handoff paths are canonicalized on Windows, and stable/prerelease channel documentation is current.

Install

go install github.com/gentleman-programming/gentle-ai/v2/cmd/gentle-ai@v2.4.0-rc.3

Or download a binary below and verify it against SHA256SUMS.txt.

After upgrading, run gentle-ai sync. Managed assets are version-bound to the binary.

A note on v2.4.0-rc.2

v2.4.0-rc.2 was published without binaries and could not be repaired: its release is immutable, so assets can never be attached after publication, and deleting it burned the tag name permanently. This candidate carries everything rc.2 contained plus the Windows work above. Use this one; rc.2 has no artifacts and will not get any.

Known open

Negotiated recovery can still print --agent <your-runtime-identity> when the runtime is unbound. Supplying a logical orchestrator role there fails closed correctly but strands the workflow; #2885 tracks replacing that free-form guess with provider-owned recovery.

v2.4.0-rc.1 β€” Every refusal names its exit

Choose a tag to compare

@Alan-TheGentleman Alan-TheGentleman released this 08 Aug 21:12
Immutable release. Only release title and notes can be modified.
3d1e673

Why this is 2.4.0 and not 2.3.1

Every commit since v2.3.0 is a fix. There is no feat and no !. By convention that is a patch, and it would have been the wrong call: two of those fixes change the negotiated contract in ways a consumer can observe at runtime.

  • The abandon maintainer authorization moved from v1 to v2 as a clean break. A stored v1 token is now refused, with the message naming the exact rerun that produces a v2 one.
  • Two transitions stopped reporting kind: stop and now report kind: collect. Their reason_code values are byte-identical on purpose, so a consumer routing on the code is unaffected; one routing on kind sees something new.

Neither breaks a Go API or a build. Both are behavior changes to a published contract, so they get a minor and a release note instead of a surprise.

Reviews stop being dead ends

The theme of this release is refusals that used to end the conversation and now hand you a command.

A failed verification with an unchanged candidate and budget left reported a lifecycle deadlock. It never was one: rescope had owned that transition since #2298, and nothing said so. Both reset and rescope now name the exits that actually run from the state you are in, including the route to a wider budget, which rescope structurally cannot give you.

A completed objective refused a repeated begin and named no successor, though changing --work-unit was the whole difference. The maintainer-decision block told you to rescope, which is structurally impossible in the one state that printed it. A wrong exit is worse than a missing one: a dead end tells you to stop, advice that cannot work sends you in circles.

Two negotiated transitions that reported stop for a state you can fix by supplying one value now collect that value instead.

Damaged authority stops blocking everything else

One unreadable record used to fail the whole per-repository inventory closed, across every worktree sharing the common dir. Four authority walks now treat it as absent from the graph, so a single bad edge no longer blocks unrelated reviews, recovery or abandonment. The repair surface got the same treatment: a disposition plan is no longer refused because some unrelated entry carries a diagnostic.

review abandon generalizes to any non-terminal lineage under one maintainer authorization, so a wedged review finally has a sanctioned exit.

Installed assets are checked against their content

Reviews now refuse to run against managed assets that disagree with the binary, and the check compares a digest of the assets themselves, not a build identity. A rebuild that changes no asset no longer declares your installation stale.

It refuses only a recorded digest that disagrees. If you never ran gentle-ai install, nothing is stale and nothing is blocked.

Also in this release

Every failure envelope now carries the native cause instead of a constant message, and the SDD binding names which of its twelve integrity conditions failed. Persona resolution stops drifting: gentleman-neutral-artifacts now means neutral, as its name always promised, and migrates once with a notice. Windows NUL config paths in the isolated Git view are fixed. Codex, OpenCode and Claude Code share one advisory reviewer transport.

Install

go install github.com/gentleman-programming/gentle-ai/v2/cmd/gentle-ai@v2.4.0-rc.1

Or download a binary below and verify it against SHA256SUMS.txt.

After upgrading, run gentle-ai sync. Managed assets are version-bound to the binary and reviews now refuse a mismatch.

Known open

Two linked-worktree handoff tests fail on Windows (#2783). The lane is green otherwise, and that count is now tracked rather than unknown.

v2.3.0 β€” The RC That Held

Choose a tag to compare

@github-actions github-actions released this 08 Aug 00:17
Immutable release. Only release title and notes can be modified.
d299eb8

v2.3.0 β€” The RC That Held

v2.3.0 is the exact v2.3.0-rc.3 candidate promoted to stable after community testing. Community feedback validated the candidate and made the release boundary clear.

Provenance: the v2.3.0 tag peels to RC3 SHA d299eb8a4009f770a605174410b0cbacc5c7524f. This stable release contains those RC3 bytes only, not later changes on main.

Upgrade now

brew upgrade gentle-ai

Run gentle-ai sync after upgrading. Replacing the binary does not refresh the managed runtime assets already installed for your agents.

What the RC3 evidence proved

SDD runs the role you assigned

The executor contract is now stated before any delegation instruction in all nine delegate_only skills. An SDD phase agent no longer commits to delegating before learning that the executor exception applies to it.

Review results scale and retain their meaning

  • Reviewer context for large candidates is prepared once and reused. Candidates beyond the evidence limit now receive a bounded refusal that names the real limit and actionable next step.
  • An approved receipt survives the staged-to-commit representation change when the base tree, candidate tree, changed paths, and digest are identical. Overlay reviews remain deliberately separate.
  • Negotiated STATUS can forecast the current step beside its transition, replacing an avoidable try, error, fix, retry loop with an explicit forecast.

Runtime behavior matches the environment

  • OpenCode-bound review starts now record the real OpenCode runtime identity in their consent envelope.
  • WSL rejects Windows npm shims when resolving CodeGraph, and installation rollback includes the affected plugin state.
  • Engram resolves the correct project identity from linked worktrees, so observations remain attached to the intended project.
  • A maintainer-authorized provider recovery remains authorized instead of being overwritten by defect handoff.
  • Windows reliability improved through the plugin rollback fix and a split for the oversized test shard.

Known issues in these exact RC3 bytes

These are the limitations recorded for the promoted RC3 candidate. They describe release scope, not the current state of every linked issue or every runtime.

  • Native admission can still reject some non-empty reviewer findings (#2482) and two of four lenses on scope_changed successors (#2618).
  • sdd-verify-validate rejects every requirements value against an Engram store (#2500).
  • The managed OpenCode permission profile can deny review.start (#2615) and still references an undo-checkpoint operation that does not ship (#2595).
  • On Windows, a NUL attributes-file quirk can block review start before any mutation (#2358).
  • A corrupted authority edge still has no sanctioned quarantine path (#2014). The repository-wide blocking it originally caused is fixed; the stuck edge remains a design question.
  • HIGH-tier corrections can dead-end after conflicting evidence (#2623).
  • Claude Code has unit and conformance coverage but no organic terminal-review proof. #2692 and #2566 remain the evidence boundary for that path.

Install and integrity

For an existing Homebrew installation, use the upgrade command above. For a first Homebrew install:

brew install gentleman-programming/tap/gentle-ai

If Homebrew is not your path, install the tagged Go module and then refresh the managed assets:

go install github.com/gentleman-programming/gentle-ai/v2/cmd/gentle-ai@v2.3.0

The release includes four Darwin/Linux .tar.gz archives: darwin_amd64, darwin_arm64, linux_amd64, and linux_arm64. checksums.txt contains their SHA-256 digests, and checksums.txt.minisig is the detached Minisign signature for that manifest. Verify the signed checksum manifest before using a raw archive.

The Windows stable binary is intentionally omitted under the existing Authenticode policy.

Community evidence

This stable release is the RC3 candidate that community testing held to account. Keep reporting real runs, especially full reviews in the runtime you use. Evidence is how the next release gets better.

v2.3.0-rc.3 β€” What rc.2 taught us in a day

Choose a tag to compare

@Alan-TheGentleman Alan-TheGentleman released this 07 Aug 17:22
Immutable release. Only release title and notes can be modified.
d299eb8

Gentle AI v2.3.0-rc.3: What rc.2 taught us in a day

rc.2 went out and the reports started arriving within the hour. Most were right. Several were older defects that rc.2 finally made reachable. Two were ours from the night before. This build is what came back.

It is a prerelease for community testing. Please keep breaking it.

If you are upgrading, run this

gentle-ai sync

Replacing the binary does not refresh the runtime assets already installed for your agents. One rc.2 report turned out to be an rc.1 OpenCode plugin running under an rc.2 binary, failing with a message rc.2 cannot even produce (#2442). Our own install instructions caused that. Detecting the skew automatically is tracked in #2685.

Fixed since rc.2

SDD phase agents could refuse to work

An sdd-init executor announced it was the orchestrator and blocked with no artifacts, because the installed skill told it to delegate before telling it that instruction did not apply to it (#2697, #721). A model reads forward, so it committed to delegating before learning it should not, then found no delegation primitive because it already was the executor.

Every delegate_only skill now states one role contract in which each instruction follows the condition that scopes it, and a test fails if anyone reintroduces an instruction plus its retraction. Nine skills carried this, not the one originally reported. Credit to @chrisssp, who diagnosed it in May and whose fix is preserved in this history.

Reviewer context on large candidates

A 208-file candidate hit a fixed 120-second deadline before the first reviewer ever launched (#2693). The deadline was not the cause: assembling one lens context rebuilt the entire frozen candidate view on every single read, roughly twelve git processes per path instead of one, about 2,500 processes for that candidate and four times that across four lenses.

That work is now prepared once and reused. A candidate that exceeds the reviewer evidence limit also refuses immediately now, naming the real limit and what to do about it, instead of timing out after thousands of processes with an instruction to retry that could never succeed.

Receipts surviving a commit

An approved receipt from a staged review stopped governing once the same content was committed and evaluated as a committed range, even though base tree, candidate tree, changed paths, and digest were all identical (#2688). Governance now recognizes that pair as the same content. The overlay kind stays deliberately separate, because it can carry intervening commits a current-changes review never inspected, and a test asserts that exclusion rather than assuming it.

Reported by you, fixed here

  • The consent envelope reported claude-code for an OpenCode-bound start (#2676).
  • WSL resolved a Windows npm shim for CodeGraph and left a partial rollback (#2680).
  • Engram inferred the wrong project inside linked worktrees, so observations never matched (#2682).
  • The provider defect handoff overrode an explicitly authorized recovery (#2679).
  • Negotiated STATUS can now carry a forecast of the current step beside the transition (#2664).
  • Windows: a plugin rollback regression and an oversized test shard, both caught by our own Windows suite before this release (#2701).

Known issues going in

Same honesty section as always. Open, real, and being worked by root cause rather than one at a time:

  • Native admission still rejects some reviewer results too aggressively: non-empty findings on certain candidates (#2482) and two of four lenses on scope_changed successors (#2618).
  • sdd-verify-validate rejects every requirements value against an Engram store (#2500).
  • The managed OpenCode permission profile can deny review.start itself (#2615) and references an undo-checkpoint operation that does not ship (#2595).
  • Windows: a NUL attributes-file quirk can block review start before any mutation (#2358).
  • A corrupted authority edge still has no sanctioned quarantine path (#2014). The repository-wide blocking it originally caused is fixed; the stuck edge itself is a design question we are not rushing.
  • HIGH-tier corrections can dead-end after conflicting evidence (#2623).
  • Claude Code's reviewer path has unit and conformance coverage but no organic proof, so #2692 and #2566 stay open until a real Claude run completes a review to a terminal receipt. OpenCode and Codex both have that evidence. Claude does not, and we are not closing those on design alone.

What we want you to try

Ordered by how much we want the answer.

1. sdd-init on a clean project from OpenCode. The exact flow that blocked in rc.2. It should initialize and return its result contract.

2. A large review. A hundred files or more, high risk, four lenses. Tell us what refuses and whether the refusal names something you can actually do.

3. Stage your reviewed files, commit, and push. The approved receipt should survive the representation change instead of dying at the gate.

4. A full review on each runtime you use. OpenCode from an ordinary session, Codex, and Claude Code. Claude is the one we most want to hear about, because it is the one without organic proof.

Installing it

This prerelease does not update Homebrew, and the binaries are unsigned. Integrity comes only from SHA256SUMS.txt, so verify before running.

Linux and macOS

# pick your platform: linux_amd64, linux_arm64, darwin_amd64, darwin_arm64
PLATFORM=linux_amd64
VERSION=2.3.0-rc.3

curl -fsSLO "https://github.com/Gentleman-Programming/gentle-ai/releases/download/v${VERSION}/gentle-ai_${VERSION}_${PLATFORM}"
curl -fsSLO "https://github.com/Gentleman-Programming/gentle-ai/releases/download/v${VERSION}/SHA256SUMS.txt"

# verify before running it
sha256sum --ignore-missing -c SHA256SUMS.txt

chmod +x "gentle-ai_${VERSION}_${PLATFORM}"
sudo mv "gentle-ai_${VERSION}_${PLATFORM}" /usr/local/bin/gentle-ai
gentle-ai --version   # expect: gentle-ai 2.3.0-rc.3
gentle-ai sync        # refresh managed assets, see the note at the top

On macOS, Gatekeeper will quarantine an unsigned binary. Clear it with xattr -d com.apple.quarantine /usr/local/bin/gentle-ai.

Windows (PowerShell)

$Version = "2.3.0-rc.3"
Invoke-WebRequest -Uri "https://github.com/Gentleman-Programming/gentle-ai/releases/download/v$Version/gentle-ai_${Version}_windows_amd64.exe" -OutFile gentle-ai.exe
Invoke-WebRequest -Uri "https://github.com/Gentleman-Programming/gentle-ai/releases/download/v$Version/SHA256SUMS.txt" -OutFile SHA256SUMS.txt

# compare this against the windows line in SHA256SUMS.txt
Get-FileHash gentle-ai.exe -Algorithm SHA256 | Format-List

.\gentle-ai.exe --version
.\gentle-ai.exe sync

Going back

Keep your current binary before overwriting it, or reinstall the stable release with brew install gentleman-programming/tap/gentle-ai. Reviews completed on this build use the rc.2 identity format; an older binary treats them as it treats any receipt it cannot match, by failing closed.

v2.3.0-rc.2 β€” One contract, three runtimes

Choose a tag to compare

@Alan-TheGentleman Alan-TheGentleman released this 07 Aug 00:00
Immutable release. Only release title and notes can be modified.
d94dc00

Gentle AI v2.3.0-rc.2: One contract, three runtimes

rc.1's three known issues are fixed, the reviewer transport was rebuilt around one shared contract, and the first three fixes from the new root analysis landed. This build removes more machinery than it adds, again.

It is a prerelease for community testing. Please break it.

Fixed since rc.1

The three defects called out at the top of rc.1's notes:

  1. The documented negotiated invocation works. The preflight gate that refused the documented form was replaced by shared-contract capability admission (#2207), and CI re-runs the negotiated continuation journey on every build as evidence.
  2. OpenCode and Codex complete reviews. The transport gate that declared them eligible and then refused them is gone (#2657). OpenCode reviews run from your ordinary, already-running session: no restart, no special terminal, no OPENCODE_DISABLE_PROJECT_CONFIG/OPENCODE_DISABLE_EXTERNAL_SKILLS variables, and the plugin shrank from 793 to 350 lines. Codex is supported for the first time, activated on a real organic proof that ran a full review to a pre-push allow with a poisoned-worktree control.
  3. The protocol no longer tells your orchestrator to refuse prereleases. The "installed released fix" wording was corrected across all managed assets.

What is new

One advisory reviewer contract

Reviewer transport is now a single Go-owned contract: the provider derives the evidence from frozen authority, renders one canonical prompt per lens, and validates raw model output through native admission. Runtime adapters only carry the prompt and return text. A model can never mint a receipt, declare PASS, or open a gate, whatever it reads or returns. An adapter-minimality guard makes reintroducing business logic in an adapter a build failure.

The representation root, fixed at the source

Three fixes from the root analysis in #2471 (root 21: the system compared where your content lived instead of what it was):

  • Snapshot identity is content-addressed (#2659). Byte-identical candidates now carry the same identity regardless of Git representation.
  • Zero-delta candidates refuse on every route (#2586). A plain review start on a clean worktree can no longer mint an approved receipt that inspected nothing; the refusal names the --base-ref rerun for committed work.
  • Compatible base advance carries a per-gate policy (#2665), plus a latent pre-push freshness fix. If your approved base-diff receipt died because a teammate merged unrelated work, re-verify on this build: the disjoint-advance case recovers without a local merge (#2388 has the evidence).

Upgrade note: in-flight reviews start fresh

Identity purification is a clean break by design. Review lineages and receipts created by v2.2.4 or rc.1 that are still in flight will validate as outdated on this build: run a fresh review to mint new authority. Historical records remain readable; they simply no longer govern gates. Nothing in your Git history is touched.

Installing it

This prerelease does not update Homebrew, and the binaries are unsigned. Integrity comes only from SHA256SUMS.txt, so verify before running.

Linux and macOS

# pick your platform: linux_amd64, linux_arm64, darwin_amd64, darwin_arm64
PLATFORM=linux_amd64
VERSION=2.3.0-rc.2

curl -fsSLO "https://github.com/Gentleman-Programming/gentle-ai/releases/download/v${VERSION}/gentle-ai_${VERSION}_${PLATFORM}"
curl -fsSLO "https://github.com/Gentleman-Programming/gentle-ai/releases/download/v${VERSION}/SHA256SUMS.txt"

# verify before running it
sha256sum --ignore-missing -c SHA256SUMS.txt

chmod +x "gentle-ai_${VERSION}_${PLATFORM}"
sudo mv "gentle-ai_${VERSION}_${PLATFORM}" /usr/local/bin/gentle-ai
gentle-ai --version   # expect: gentle-ai 2.3.0-rc.2

On macOS, Gatekeeper will quarantine an unsigned binary. Clear it with xattr -d com.apple.quarantine /usr/local/bin/gentle-ai.

Then refresh your managed assets. This step is not optional.

gentle-ai sync

Replacing the binary does not update the runtime assets already installed for your agents, and a stale asset fails with messages from its own older vintage that no longer exist in this build. One community report already hit exactly that: an rc.1 OpenCode plugin under an rc.2 binary, rejecting reviewer launches with a message rc.2 cannot produce (#2442). Detecting that skew automatically is tracked in #2685.

Windows (PowerShell)

$Version = "2.3.0-rc.2"
Invoke-WebRequest -Uri "https://github.com/Gentleman-Programming/gentle-ai/releases/download/v$Version/gentle-ai_${Version}_windows_amd64.exe" -OutFile gentle-ai.exe
Invoke-WebRequest -Uri "https://github.com/Gentleman-Programming/gentle-ai/releases/download/v$Version/SHA256SUMS.txt" -OutFile SHA256SUMS.txt

# compare this against the windows line in SHA256SUMS.txt
Get-FileHash gentle-ai.exe -Algorithm SHA256 | Format-List

.\gentle-ai.exe --version
.\gentle-ai.exe sync   # refresh managed assets; see the note above

Going back

Keep your current binary before overwriting it, or reinstall the stable release with brew install gentleman-programming/tap/gentle-ai. Reviews completed on this build use the new identity format; a v2.2.4 binary treats them as it treats any receipt it cannot match, by failing closed.

What we want you to try

Ordered by how much we want the answer. If you only have time for one, do the first.

1. A full review from your ordinary OpenCode session. No restart, no environment variables, no special terminal. Take a real change through review and delivery. If anything asks you to restart or set an OPENCODE_DISABLE_* variable, that is a bug in this build's headline feature.

2. A full review on Codex. First supported build. Real change, full lifecycle, through a delivery gate. Tell us especially about refusals that name no next action.

3. Stage your reviewed untracked files. Get a review approved, then git add previously untracked reviewed files and commit. On rc.1 this could kill your receipt (#2361); on this build the receipt should survive the representation change. The reports there predate the fixes, so fresh evidence either way decides that issue.

4. Review after a teammate merges. Approve a base-diff review, let unrelated work land on the parent, then push. The disjoint case should recover without re-review. If you locally merged the advanced parent, a refusal is correct and expected; tell us if the message does not make that clear.

5. review start on a clean tree. Should refuse immediately, naming --base-ref for committed work, on every invocation form. If you find any route that freezes an empty candidate, we want it badly.

6. Delivery gates end to end. Commit, push, PR, with and without an approved receipt. Same receipt validated at every gate, review never reopened for unchanged content.

Known issues going in

Honesty section, same as rc.1. These are real, open, and being worked by root:

  • Native admission can reject reviewer results too aggressively: any non-empty findings on some candidates (#2482), two of four lenses on scope_changed successors (#2618). If a review that plainly found something real gets out_of_scope, it is these.
  • sdd-verify-validate rejects every requirements value against an Engram store (#2500).
  • The managed OpenCode permission profile can deny review.start itself (#2615) and references an undo-checkpoint operation that does not ship (#2595). A conformance guard that makes this class impossible is queued.
  • Windows: a NUL attributes-file quirk can block review start pre-mutation (#2358). Fix scoped, next build.
  • HIGH-tier corrections can dead-end after conflicting evidence (#2623); a designed disposition path is deliberately deferred rather than patched per case.

If you hit any of the above, the issue links carry current state. Everything reported on rc.1 was preserved: 3 fixed here, the rest tracked by root in #2471.