Skip to content

Releases: allocator-one/rcl

v3.6.0

Choose a tag to compare

@github-actions github-actions released this 15 Sep 13:28
928c39a
  • 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. The ask path
    now shares a 16k output budget across adapters, and a provider that stops
    at its output ceiling fails the answer with TruncatedAnswerError instead
    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 — keeps gating.verification.verdict: unavailable with the cause
    in note, but is left at the tier it earned on its own,
    gating.reason: none, instead of being promoted to verified. Consensus
    and critical findings gate as before. Harness reads gating_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.ts classifies rendered files
    by their repository-relative path, so npm test passes from a checkout
    under .claude/worktrees/.
  • GitHub Releases: the Release workflow now creates the GitHub Release for
    each vX.Y.Z tag after the npm publish, with notes taken from the matching
    CHANGELOG.md section 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

Choose a tag to compare

@mstroeck mstroeck released this 15 Sep 09:56
2293fee
  • Attested finding retriage (RCL-58): allow retriage-finding to 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 round 1 satisfies the existing Harness
    verdict wire protocol only and does not create or claim native convergence.

v3.4.0

Choose a tag to compare

@mstroeck mstroeck released this 15 Sep 10:00
36013c8
  • 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; --submit sends 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

Choose a tag to compare

@mstroeck mstroeck released this 15 Sep 10:00
02c31e2
  • 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

Choose a tag to compare

@mstroeck mstroeck released this 15 Sep 10:00
3ac3878
  • 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; --submit sends 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 use report:<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

Choose a tag to compare

@mstroeck mstroeck released this 15 Sep 10:00
712b9f0
  • 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 from HARNESS_API_URL), exchanges it at
    POST /api/v1/reviews/attest for 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 as credential_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 / _TOKEN unset),
    without HARNESS_API_URL, off a pull request target, with a telemetry level
    other than full (environment or project config), or when the exchange is
    refused (the reason is printed). Never falls back to HARNESS_API_TOKEN or
    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_processed carries the round's classification (RCL-47):
    identities: [{identity_key, matched_identity, status, suppress_reason?}]
    — each sighting's own report key, the identity converge-report matched it
    to by location, and whether it was new, repeat, suppressed or
    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
    unresolved for 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

Choose a tag to compare

@mstroeck mstroeck released this 15 Sep 10:00
63a886c
  • rcl evidence status reports a pull request nothing has been judged for
    (RCL-44). Harness sends conclusive: null for a projection without a
    judged current-head run (status none, stale, unverified); the reader
    refused every such answer as malformed, so the command failed exactly where
    it should have said "no evidence yet". conclusive is 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, url on the patch target), so Harness can
    verify its --head-sha against 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 status still reads stale/none for patch-file loops.
    A --converge-target of 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_PR only ever attributes a
    patch file). The
    rcl-converge skill 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: pending until then), reads rcl evidence status after 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 models merges 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's source; --local keeps 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_recorded events; ids are UUIDv5 of (host, repo, sha256 of the report) so a second run adds nothing. RunHeader.provenance and uuidv5
    are new; openReadSink is the shared credential-only sink for reads.

  • rcl evidence status [<pr>] and rcl evidence show <run id> (RCL-41):
    the read side of the evidence ledger. status fetches
    GET /api/v1/reviews/prs/:owner/:repo/:number — a bare N or #N is read
    against the checkout's origin remote, owner/repo#N and pull request URLs
    stand alone — and prints both projections, their rounds, the open actionable
    findings and the merge decision; --json prints the API object. Exit 0 only
    when the judged projection (--enforced or 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). show fetches
    GET /api/v1/reviews/runs/:id and 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. HarnessSink gained getGateStatus and getRun, 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

Choose a tag to compare

@mstroeck mstroeck released this 15 Sep 10:00
84b9c17

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-listed buildRunEnvelope
    wraps the report's run header with wire-shaped findings and calls, the
    report's stats, 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. An Outbox at ~/.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 a loss event on the next successful flush.
  • Credentials. The stored harness login is the default; HARNESS_API_TOKEN
    • HARNESS_API_URL serve 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
    (default full), --no-telemetry, RCL_TELEMETRY (off, 0, false,
    no, or a level name);
    harness.parseFailures opts 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-required exits 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-sha and a run with --no-telemetry,
    RCL_TELEMETRY=off or harness.telemetry: off. Under --ci the gate's
    exit code wins; the evidence failure is printed beside it. At the
    envelope and findings levels 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-notice records 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-attempt emits attempt_claimed (and
    cap_changed under --max-attempts), converge-report emits
    round_processed (and cap_changed under --max-rounds) and persists the
    round's run id in the run state, converge-verdict emits
    verdicts_recorded and resolution bound 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 as loss/<id>.json.refused,
    listed by status, 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, or http to localhost,
    127.0.0.0/8, ::1 and *.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 / --markdown are that same delivery view (a parse_failed
    call keeps only the parser message unless harness.parseFailures is 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-required flush-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 run header on every report (ReviewResult.run):
    client run id (UUIDv7), rcl version, command, target with exact
    head_sha/base_sha/refs and a diff_sha256, roster with lanes
    (blocking / secondary / async / verification), config digest with
    thresholds and gating inline, spec and context-file digests, a best-effort
    runner claim, timing, ci_exit_code (computed even without --ci), and
    the converge context. The Markdown report gains a matching Reviewed line.
  • Exact-head binding. PRMetadata gains headSha, baseSha and
    mergeCommitSha from the PR response GitHub already returns; --staged /
    --working-tree resolve HEAD and the merge-base with the remote default
    branch; --head-sha / --base-sha vouch for a patch file's commits;
    --expect-head-sha fails 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 (or RCL_CONVERGE_*) are
    recorded in the header.
  • Identity on every finding. ConsensusFinding.identity carries the
    converge stableFindingKey at review time, on kept and below-threshold
    findings alike.
  • Token usage on calls. Adapters record usage
    (inputTokens / outputTokens / reasoningTokens) where the SDK exposes
    it — Anthropic usage, OpenAI and OpenRouter usage (with
    completion_tokens_details.reasoning_tokens), Google usageMetadata
    including on truncated or refused answers; chunked reviews sum it.
  • Pre-3.0 reports (no run, no identity) load unchanged in
    converge-report, discuss, and models seed.

npm: https://www.npmjs.com/package/review-council/v/3.0.0
Tarball SHA-256: fc87079625e9bd6d83482a06b21881680a033d8aff70fd665e7d4fbabf4b09aa

v2.1.4

Choose a tag to compare

@mstroeck mstroeck released this 15 Sep 10:00
19a138c
  • 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

Choose a tag to compare

@mstroeck mstroeck released this 15 Sep 10:00
41c9de0
  • 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