Releases: allocator-one/rcl
Release list
v3.6.0
- Verifier batching (RCL-60): the verification lane sends candidates in
batches of eight, three in flight, instead of one call carrying every
candidate; past about ten candidates that single answer was cut off, parsed
to nothing, and every candidate was recorded unavailable. Theaskpath
now shares a 16k output budget across adapters, and a provider that stops
at its output ceiling fails the answer withTruncatedAnswerErrorinstead
of returning a truncated success, so an uncovered candidate records the real
cause. Contributed in #63. - Unavailable verification no longer gates (RCL-62): a candidate the
verification pass could not check — the call failed, the answer did not
cover it, its file has no diff context, or the roster has no direct-API
verifier — keepsgating.verification.verdict: unavailablewith the cause
innote, but is left at the tier it earned on its own,
gating.reason: none, instead of being promoted toverified. Consensus
and critical findings gate as before. Harness readsgating_reason, so an
attested gate run whose verifier lane failed no longer blocks on
single-model findings nobody checked. The report's gating line reads
unavailable — unverified, not gating. - Skills test:
test/skills/generated.test.tsclassifies rendered files
by their repository-relative path, sonpm testpasses from a checkout
under.claude/worktrees/. - GitHub Releases: the Release workflow now creates the GitHub Release for
eachvX.Y.Ztag after the npm publish, with notes taken from the matching
CHANGELOG.mdsection and the published tarball attached.npm publish
still runs in the minimal tokenless job; only the new final job holds
contents: write.
npm: https://www.npmjs.com/package/review-council/v/3.6.0
Tarball SHA-256: 0492dd5f8d25aa8d0d8303ba0eb4563fb7c29da6a85a1eb53c663d8794818a54
v3.5.0
- Attested finding retriage (RCL-58): allow
retriage-findingto record a
source-backed dismissal for a standalone attested gate run whose server record
has no convergence metadata. Require the exact verified same-repository CI run,
PR, report digest and finding ref. Event round1satisfies the existing Harness
verdict wire protocol only and does not create or claim native convergence.
v3.4.0
- Explicit finding retriage (RCL-56):
rcl evidence retriage-finding
previews a fresh dismissal under one immutable, run-scoped report key at its
recorded severity. Requires the exact PR, run, report digest, finding ref,
convergence target and a source-backed reason file;--submitsends one
attributed verdict through the existing Harness API. No identity rematching,
report rewriting, native history/accounting updates, outbox delivery or paid
review. Ambiguous and legacy unqualified report keys are refused. Submission
acknowledgment is not gate convergence; check the server's status separately.
npm: https://www.npmjs.com/package/review-council/v/3.4.0
Tarball SHA-256: 296b5800f2ef28922a259b21834f9512fe503e6a08dca6a1d82edf53969c7dec
v3.3.1
- Grouped verdict severity (RCL-48): retain the strongest severity seen
for each identity within its reviewed round, regardless of sighting order.
Delayed verdicts use the retained round severity instead of a later sighting
and do not replace a newer round's active verdict. Invalid severities,
unrecorded rounds and unsighted identities in retained round snapshots are
rejected before any state is written.
Existing dismissals are not upgraded automatically; later escalation to
critical still requires explicit retriage. Harness's critical-dismissal
guard and finding identity matching are unchanged. Historical grouped verdicts
need explicit retriage; upgrading the CLI alone does not repair old evidence.
npm: https://www.npmjs.com/package/review-council/v/3.3.1
Tarball SHA-256: 778cb999ee5f1d3d1ef54d0d4e679efa5edbfea874e25fcbb0b5b637c34c3e5e
v3.3.0
-
Preview-first finding recovery (RCL-52):
rcl evidence recover-finding
validates explicit run, report digest, finding ref and retained native identity
bindings. Preview is the default;--submitsends one authenticated correction.
No reviewers, new verdicts, accounting changes or unrelated outbox delivery.
Requires the Harness backend support from IO-12695 before live submission;
an acknowledgment is not convergence. Original report bytes are not retrieved
or reconstructed, and historical reports remain unchanged. -
Async patch convergence (RCL-50): collect delayed async results across
distinct immutable patch captures using the validated convergence target.
Preserve repository/worktree scope and other review modes' keys; do not
migrate previously spooled path-keyed results. Reviewer health, historical
finding handling and detached-worker lifetime are unchanged. -
Distinct report finding identities (RCL-51): consensus findings that
share a line-bucket anchor receive separate report keys, including findings
below the report threshold. All new report keys usereport:<run-id>:<key>
to separate them from native ledger keys and earlier runs' aliases, including
while the current classification is awaiting delivery. Native location
matching and existing ledger identities are unchanged. Legacy reports with
conflicting classifications for one report key fail before the round state
is written, rather than silently discarding a mapping, including missing-key
fallback and telemetry-off
use. Preserve those reports for separately supported finding-ref recovery;
this change does not relabel already-published evidence.
npm: https://www.npmjs.com/package/review-council/v/3.3.0
Tarball SHA-256: 9ce6cd82a1426f75043ffb7e5632f49c67b37548ffd6289d14d8997b64e1a03a
v3.2.0
rcl review … --attest(RCL-40): inside the organization's gate
workflow on GitHub Actions, rcl asks the runner for the job's OIDC token
(audience: the Harness origin fromHARNESS_API_URL), exchanges it at
POST /api/v1/reviews/attestfor a run-bound credential (rbc_…, thirty
minutes, one run id, valid while the Actions run is in progress) and records
the review under it — envelope, artifacts, model keys and model stats — so
Harness stores the run ascredential_kind: attested, the tier the enforced
gate reads. Fails loudly before any token is requested or any reviewer is
paid: outside Actions (ACTIONS_ID_TOKEN_REQUEST_URL/_TOKENunset),
withoutHARNESS_API_URL, off a pull request target, with a telemetry level
other thanfull(environment or project config), or when the exchange is
refused (the reason is printed). Never falls back toHARNESS_API_TOKENor
the stored login, implies--evidence-required, never spools (the
credential does not outlive the workflow run), and mints the credential
again for the same run id before delivery when a long review has used up
most of its thirty minutes.round_processedcarries the round's classification (RCL-47):
identities: [{identity_key, matched_identity, status, suppress_reason?}]
— each sighting's own report key, the identityconverge-reportmatched it
to by location, and whether it wasnew,repeat,suppressedor
regating. Harness applies a standing verdict to a key that moved with the
code only when it knows the matched identity (IO-12601); without it a
re-sighted fixed or dismissed finding reads as actionable and the gate says
unresolvedfor a loop rcl judged converged. One entry per key; text goes
through the usual scrubber.
npm: https://www.npmjs.com/package/review-council/v/3.2.0
Tarball SHA-256: 3d528d22253c37b230c31bcd308fbd57a6c047fa810e39ecbb0dd583b6fcc056
v3.1.0
-
rcl evidence statusreports a pull request nothing has been judged for
(RCL-44). Harness sendsconclusive: nullfor a projection without a
judged current-head run (statusnone,stale,unverified); the reader
refused every such answer as malformed, so the command failed exactly where
it should have said "no evidence yet".conclusiveis now boolean or null,
an unjudged projection prints without an(inconclusive)label, and the
exit status is unchanged (1, not converged). -
rcl review … --for-pr owner/repo#N(RCL-39;RCL_FOR_PR): a
patch-file review is bound to the pull request it was taken from
(target.repo,pr_number,urlon thepatchtarget), so Harness can
verify its--head-shaagainst that pull request's head; counting such a
round for the pull request's gate is the server half, IO-12585 — until it
lands,rcl evidence statusstill readsstale/nonefor patch-file loops.
A--converge-targetof the same form attributes the run too; the flag
needs--head-sha, lower-cases the names, and is refused on PR and
git-mode targets, which name their own (RCL_FOR_PRonly ever attributes a
patch file). The
rcl-convergeskill passes--converge-target '<TARGET>' --round <R> --attempt <ATTEMPT>on every launch and adds--for-pr <owner/repo#N>when
the round reviews a patch file taken from the pull request (a pull request or
git-mode target names its own), counts a
spooled round as evidence only once its flush is acknowledged (ledger
evidence: pendinguntil then), readsrcl evidence statusafter the loop
next to the machine resolution, and records that the converge ledger is
rendered by Harness (IO-12482) rather than uploaded — the server accepts
only artifacts a run declared at delivery. -
Org-wide model weights (RCL-38):
rcl modelsmerges Harness's
GET /api/v1/reviews/model-stats(the organization's window over every run
it recorded, backfilled history included) with this machine's store — the
server's weight for a model it holds ≥ 20 outcomes for, the local weight
below that, neutral for a model neither knows enough about — and shows each
row'ssource;--localkeeps to the machine. Reviews weight consensus the
same way (loadMergedWeights, three-second bound, local fallback). -
rcl telemetry backfill --from <dir> --repo <owner/repo> [--dry-run] [--json]
(RCL-38): pre-3.0 reports and converge ledgers become runs with
provenance: backfill(synthesized header bound to the repository, findings
with stable identities, reviewer calls, both report files as artifacts) and
verdicts_recordedevents; ids are UUIDv5 of(host, repo, sha256 of the report)so a second run adds nothing.RunHeader.provenanceanduuidv5
are new;openReadSinkis the shared credential-only sink for reads. -
rcl evidence status [<pr>]andrcl evidence show <run id>(RCL-41):
the read side of the evidence ledger.statusfetches
GET /api/v1/reviews/prs/:owner/:repo/:number— a bareNor#Nis read
against the checkout'soriginremote,owner/repo#Nand pull request URLs
stand alone — and prints both projections, their rounds, the open actionable
findings and the merge decision;--jsonprints the API object. Exit 0 only
when the judged projection (--enforcedor the default advisory) is
converged, 1 for any other status, 2 when the pull request cannot be
named, 3 when the read could not be answered (no credential, evidence off,
unknown pull request, refused credential, unreachable host).showfetches
GET /api/v1/reviews/runs/:idand lists the run's header, reviewer health,
artifact state and findings with identity, gating reason and verdict. Reads
use the delivery credential rules (reviews:read) and ignore the telemetry
level.HarnessSinkgainedgetGateStatusandgetRun, each refusing an
answer that is not about what was asked.
npm: https://www.npmjs.com/package/review-council/v/3.1.0
Tarball SHA-256: 7232a92ce5e89b3997f04369614fc21631a4013ade63bc8c75a6d7b61601e6f2
v3.0.0
Review Council evidence (epic IO-12475). Behavior change: in a
Harness-managed repository (one carrying .harness-cli/config.json) with a
harness login, a review now records itself on Harness by default — the run
header, consensus findings (which quote code), reviewer call statistics and
the JSON and Markdown reports as written. Hence the major version; every
report field is additive and pre-3.0 reports load unchanged.
src/telemetry/(RCL-37): a pure, allow-listedbuildRunEnvelope
wraps the report'srunheader with wire-shaped findings and calls, the
report'sstats, the SHA-256 digests of the exact bytes written to
--json-file/--markdown, and how the delivery came about.HarnessSink
posts the envelope, PUTs each declared artifact and posts converge events
under a 10 s timeout per request, sending the token only to the host that
minted it. AnOutboxat~/.rcl/outbox/<run id>/keeps what Harness could
not take and retries it — same run id,delivery: {mode: retried, spooled_at}— at the start of every command (five-second bound) or via
rcl telemetry flush; above 1 GB it stops spooling artifacts and reports the
affected runs as alossevent on the next successful flush.- Credentials. The stored
harness loginis the default;HARNESS_API_TOKENHARNESS_API_URLserve CI, and an environment token never pairs with the
stored host (half a pair is an error, not a fallback). A base URL carries no
user-info, query or fragment; a trailing slash is normalized away.
- Configuration.
harness.telemetry: off | envelope | findings | full
(defaultfull),--no-telemetry,RCL_TELEMETRY(off,0,false,
no, or a level name);
harness.parseFailuresopts in to a parse-failed call's raw answer (fenced
code and key-shaped strings removed, 32 KB cap) — by default only the parser
message travels. --evidence-requiredexits 4 when the evidence is incomplete — the
envelope was not acknowledged (spooled, refused, or the org has evidence
off), or a declared artifact was spooled or refused — and refuses a patch
file without--head-shaand a run with--no-telemetry,
RCL_TELEMETRY=offorharness.telemetry: off. Under--cithe gate's
exit code wins; the evidence failure is printed beside it. At the
envelopeandfindingslevels the declared artifact digests still
describe the reports rcl wrote — the server shows them as declared, not
received — and evidence is complete once the envelope is acknowledged.- Consent. The first delivery from a machine to a host prints a one-time
notice;~/.rcl/telemetry-noticerecords it. - Status line.
Evidence recorded: <url>·Evidence spooled (Harness unreachable); run rcl telemetry flush·Evidence not sent: <host> has not enabled review evidence for this organization. - Converge events.
converge-attemptemitsattempt_claimed(and
cap_changedunder--max-attempts),converge-reportemits
round_processed(andcap_changedunder--max-rounds) and persists the
round's run id in the run state,converge-verdictemits
verdicts_recordedandresolutionbound to that run id. rcl telemetry status | flush [--run <id>]for operators. Loss
reports go out in batches and are only removed once the server accounts
for every event; a refused batch is kept asloss/<id>.json.refused,
listed bystatus, never retried. A flush bounded by a deadline bounds
each request by what remains of it, and reports loss reports still
pending.- Transport hardening. Receipts larger than 64 KB are refused unread; a
WHATWG opaque redirect reads as a redirect; the credential's URL is
re-validated when the sink is built (https, orhttptolocalhost,
127.0.0.0/8,::1and*.localhost— the host comes from the login or
the environment, never from the repository). The consent notice precedes
the first transmission of any kind, converge events and flushes included. - Scrubbing. Every free-text field that leaves the process (errors,
warnings, runner claims, finding prose, consensus excerpts) is truncated and
scrubbed for bearer/key-shaped substrings. The reports written to
--json-file/--markdownare that same delivery view (aparse_failed
call keeps only the parser message unlessharness.parseFailuresis set),
so the uploaded artifacts are byte-identical to the files; with telemetry
off the raw report is written as before. - Transport. The Harness credential travels over TLS only, except to
loopback hosts (a local development server); a 401 keeps a spooled entry
for retry after re-login instead of failing it for good. - The rcl and rcl-converge skills document the evidence line, the
--evidence-requiredflush-retry rule (five minutes, then stop the loop),
and the opt-outs.
Phase 0 of the Review Council evidence ledger (RCL-36, epic IO-12475): the
report now says what it reviewed. The one network change: PR mode now
fetches the changed files through a compare pinned to the PR's base and head
object ids (GET /compare/{base}...{head}) for PRs up to GitHub's 300-file
compare cap, so the report's head_sha provably identifies the reviewed
patches even if the PR moves mid-fetch; larger PRs use the paged files
listing bracketed by PR reads and refuse to bind if the head or base moved.
- Self-describing
runheader on every report (ReviewResult.run):
client run id (UUIDv7), rcl version, command, target with exact
head_sha/base_sha/refs and adiff_sha256, roster with lanes
(blocking/secondary/async/verification), config digest with
thresholds and gating inline, spec and context-file digests, a best-effort
runnerclaim, timing,ci_exit_code(computed even without--ci), and
the converge context. The Markdown report gains a matching Reviewed line. - Exact-head binding.
PRMetadatagainsheadSha,baseShaand
mergeCommitShafrom the PR response GitHub already returns;--staged/
--working-treeresolveHEADand the merge-base with the remote default
branch;--head-sha/--base-shavouch for a patch file's commits;
--expect-head-shafails fast when the resolved head is not the expected
one — checked before the empty-diff exit, so a moved target never reads as a
clean round. --spec-source(flag|repo_file|harness_issue:<ID>) and
--converge-target/--round/--attempt(orRCL_CONVERGE_*) are
recorded in the header.- Identity on every finding.
ConsensusFinding.identitycarries the
convergestableFindingKeyat review time, on kept and below-threshold
findings alike. - Token usage on calls. Adapters record
usage
(inputTokens/outputTokens/reasoningTokens) where the SDK exposes
it — Anthropicusage, OpenAI and OpenRouterusage(with
completion_tokens_details.reasoning_tokens), GoogleusageMetadata—
including on truncated or refused answers; chunked reviews sum it. - Pre-3.0 reports (no
run, noidentity) load unchanged in
converge-report,discuss, andmodels seed.
npm: https://www.npmjs.com/package/review-council/v/3.0.0
Tarball SHA-256: fc87079625e9bd6d83482a06b21881680a033d8aff70fd665e7d4fbabf4b09aa
v2.1.4
- Oversized single-file patches are reviewed losslessly. The chunker now
emits sequential fragments with accurate unified-diff continuation headers
instead of dropping every line after the first 2,000; malformed oversized
patches fail closed rather than producing incomplete review evidence. A
blocking reviewer contributes only after every fragment succeeds, and hard
32-chunk / 512-call limits stop pathological paid-work fanout before dispatch. - Verification keeps the reported lines in view. Large hunks are excerpted
around every finding with accurate synthetic coordinates instead of blindly
keeping the first 4,000 characters. If all referenced ranges cannot fit, the
finding remains gating and is marked unavailable to the verifier.
npm: https://www.npmjs.com/package/review-council/v/2.1.4
Tarball SHA-256: 7c188b34056d7383c5be08581099c17821eced861f74bc0a36995bc724a9cd98
v2.1.3
- Fix trusted-publishing tag validation when Actions checkout has materialized
the pushed annotated tag as a conflicting local ref. The validation job now
force-refreshes only its local tag from the immutable protected remote tag
before checking its object type, peeled commit, ancestry, and package version.
npm: https://www.npmjs.com/package/review-council/v/2.1.3
Tarball SHA-256: f69864f9b156b9157929f570fc8a8cab974899df277f7a024c1af3f8cfb927a9