Repository navigation
Releases: seanleecoder/code-tribunal
Release list
Code Tribunal 2.1.0
Added
- Review health in the summary comment (SPEC-66). Every published run now
creates or refreshes the summary comment, including a clean run with no
findings. Its first section shows afull,degradedorre-run recommended
grade, the completed review and critique jobs, panel-wide finding counts, each
failed job with its redacted error, and one action line. Collapsed run details
give each job's model, effort, outcome and duration. A failed panel is still
not published; the consensus job log now prints the same health report
before exiting 3. Consensus reads the adapter status files through a new
--status-dirargument, which both canonical templates pass, and writes the
record asrun_health, an optional property ofconsensus.v2. Health never
changes a decision,panel_statusor an exit code. Post refuses a consensus
artifact withoutrun_health, which means one from an earlier release. Each
existing summary comment is refreshed once on the next run.
Changed
- Inline threads hash only their rendered text (N12), as the summary comment
already did. The marker'ssource=is no longer read and is written as 64
zeros, so 2.0.3 can still read 2.1.0 markers after a rollback; markers with
or without it remain valid. Each existing bot-authored inline thread surfaced on
its next run is edited once in place, with the same issue ID and state record;
its visible text is unchanged.group.body_hashinconsensus.jsonis now
always 64 zeros: posting computes the hash from the body it publishes, and the
field is removed inconsensus.v3. - Consensus no longer re-checks values the adapter runner computes: a finding
batch's counts, itsusable_for_resolutionflag, and itsmodel(N15). The
schema still bounds the counts, and the config-digest binding covers the
model. A critique whoseduplicate_of_source_finding_idnames no finding in
the run now counts as adispute, like any other unusable duplicate link,
instead of failing consensus. - Contributor tooling: Renovate keeps the npm, Python, image-digest and action
pins current, andmake qualityruns zizmor's pinning audits over the GitHub
Actions workflows. The in-repo pin checker keeps only the checks neither tool
makes, and now requires every DockerfileFROMto be digest-pinned. Nothing
changes for consumers. - Release process (ADR-0004):
a release is the SSH-signed tag whose canonical templates pin both images by
digest, published only after a cited Candidate Canary run on those digests is
verified. The release body is the version's CHANGELOG section followed by its
identity: runtime source, release commit, both image references, the canary
verdicts, and thegh attestation verifycommand. Releases no longer attach a
release manifest or checksum asset,release/<version>.mdnotes and
release/release-inputs.jsonare no longer published, and tags carry a
Canary-run:trailer instead ofRelease-manifest-sha256. Releases up to 2.0.3
are unchanged. The generated evidence records are gone fromdocs/evidence/;
each earlier release's records remain at its tag. - Upgraded reviewer CLIs to Claude Code 2.1.303, Codex 0.163.0, OpenCode
1.19.3, and Cursor Agent 2026.10.18-ea085cb; refreshed the Python, Node builder
and Debian base image digests, Node to 26.12.0, certifi to 2026.10.18, rpds-py
to 2026.9.1, and Ruff to 0.17.1. OpenCode remains paired with its expected
ripgrep 15.1.0.
Release identity
- Runtime source (R):
6ca538106d1eef7f449e5227408c99013c75aedc - Release commit (P):
a965da627ac866461bdcf6630f0897d00e4d28c9 - Base image:
ghcr.io/seanleecoder/code-tribunal/ai-review-base:2.1-6ca538106d1eef7f449e5227408c99013c75aedc@sha256:d855b177b4bfcd109f7cf1c8d86908a98dc22e83c4fbce911fdad4a68ccdaa52 - Reviewer image:
ghcr.io/seanleecoder/code-tribunal/ai-review-reviewer:2.1-6ca538106d1eef7f449e5227408c99013c75aedc@sha256:280c858d58ceee662c95f02455bb6da3846802a5d19234dc28872c02df8fa985 - Candidate Canary: https://github.com/seanleecoder/code-tribunal/actions/runs/39315351495
- panel / github: full panel, 7 threads posted, cleanup succeeded
- panel / gitlab: full panel, 2 threads posted, cleanup succeeded
- lifecycle / github: 7/7 steps passed
- lifecycle / gitlab: 6/6 steps passed
- hostile / gitlab: 5/5 steps passed
- Publication: https://github.com/seanleecoder/code-tribunal/actions/runs/39320078400
Verify an image's build provenance, for example the reviewer image:
gh attestation verify oci://ghcr.io/seanleecoder/code-tribunal/ai-review-reviewer:2.1-6ca538106d1eef7f449e5227408c99013c75aedc@sha256:280c858d58ceee662c95f02455bb6da3846802a5d19234dc28872c02df8fa985 \
--repo seanleecoder/code-tribunal \
--predicate-type https://slsa.dev/provenance/v1 \
--source-ref refs/heads/main --source-digest 6ca538106d1eef7f449e5227408c99013c75aedc \
--cert-identity https://github.com/seanleecoder/code-tribunal/.github/workflows/publish-ai-review-images.yml@refs/heads/mainCode Tribunal 2.0.3
Code Tribunal 2.0.3
Release identity
- Release:
2.0.3 - Tag:
v2.0.3 - Release inputs:
release/release-inputs.json,status: active - Runtime source
R:10f2f8deef3ee63c952df76d5f627ed6aa2e7ea9 - CI run:
39124138106 - Image publication run:
39124138105 - Base image:
ghcr.io/seanleecoder/code-tribunal/ai-review-base:2.0-10f2f8deef3ee63c952df76d5f627ed6aa2e7ea9@sha256:e6ca87a2082cd4820b780a14164212a33e3d176812541e9ede68dd1b2169ccdd - Reviewer image:
ghcr.io/seanleecoder/code-tribunal/ai-review-reviewer:2.0-10f2f8deef3ee63c952df76d5f627ed6aa2e7ea9@sha256:4279949eadccc6333ce6b07263e7ee5097e25eda49e62e9bc72fdb118614f4a6
Scope
This compatible patch refreshes the default roster to Claude Haiku 5.5 / low,
GPT-6 Luna / low, and DeepSeek V4.1 Flash / low. Cursor stays off the default
roster with Composer 2.5. It keeps one review and one critique round and the
deterministic informational consensus policy.
Findings are no longer lost silently. A finding that a majority of critics call
noise is listed under the summary's FYI findings instead of disappearing, and a
noise vote no longer resolves an existing thread. A finding that omits
confidence is kept at 0.0 instead of being dropped. Every summary entry shows
Found by.
Every stage is now bound to prepare's whole effective configuration. A job that
sees different AI_REVIEW_* overrides fails before any provider call or platform
write, and post refuses a consensus artifact from another run. Prompts and rules
always come from the image. Prepare removes every reviewer CLI's agent files
(AGENTS.md, CLAUDE.md, .claude/, and the others) from the snapshot for all
seats.
Posting state no longer grows with every run, which could overflow it and stop
post from publishing. Post ignores summary-marker notes from other authors, and an
ambiguous remap marks candidate threads stale instead of resolving them.
Output formats change only within their versions. consensus.v2 keeps the drop
decision and summary.drop_count, which are now never produced (COMPAT-003). The
prepare manifest drops config_sha256 and rules_sha256, and prepare no longer
writes the unread inputs/prompts/, inputs/rules/, and
inputs/config.review.yaml. Configuration remains review_config.v3; state_schema_version: 1 and
render-body.v4 are unchanged. The images no longer ship unread repository files
under /opt.
The hardened GitLab child pipeline is deprecated and will be removed in the next
major release (COMPAT-004).
Migration
Adopt the synchronized templates and digest-pinned image pair together, and run
every job of a pipeline on the same release: the effective-config digest changes
once, and a mixed pipeline fails at the first stage that compares it. Existing
configuration and persisted state need no schema migration.
Deployments without model or effort overrides move to the new default roster.
Set AI_REVIEW_<REVIEWER>_MODEL and AI_REVIEW_<REVIEWER>_EFFORT to keep the
2.0.2 models; see
effort inheritance and clearing.
Custom configurations that omit the inline posting settings now get multiline
comments and all three diff sides. To keep the previous behaviour, set
posting.v1_inline_sides: [new] and posting.inline_multiline: false. Remove an
unsupported posting.fyi_mode, which is now rejected, or set it to
summary_comment. See
posting and state.
A custom configuration whose prompts or rules sit beside the file that
AI_REVIEW_CONFIG names no longer has them read. Build a custom image to change
them.
GitLab installations on the hardened child should move to a protected direct
include; see the
GitLab guide.
Live campaign
| Record | Result |
|---|---|
| record-candidate-canary.md | Passed |
| record-github-current-image.md | Passed |
| record-gitlab-current-image.md | Passed |
| record-gitlab-hostile-mr.md | Passed |
| record-model-effort-routes.md | Passed |
| record-github-revision-failures.md | Registered waiver; reason in release inputs |
Release gates
- Run the scoped campaign against one frozen runtime source
Rand the final
base/reviewer pair. - Record only sanitized evidence; keep private consumer coordinates out of the
public repository. Audit withscripts/scan_evidence_leaks.pyand record its
exact scope. - Activate the release inputs only after every non-waived release-gating record
binds to the same source and image digests. - Keep
candidate-canary.ymlunchanged: the 2.0.3 evidence generator rejects
unexpected artifacts.
Tagging
The external manifest binds release_commit and re-derives the R..P diff, so the
tag must point at a commit that satisfies it.
- Merge the single release PR with a merge commit. Check out that final merged
commit asP, then runmake release-manifest P=<full SHA>. - Inspect
R..P, the manifest, checksum, and generated tag certificate before
signing. Signv2.0.3locally on exactlyP, using the generated message. - The signed certificate's
Release-manifest-sha256binds the manifest bytes.
Any change of tag target requires rebuilding and revalidating the certificate. - Push the signed tag and verify automatic publication of these notes and both
assets. CI never holds the signing key.
Carried known limitations
- In-pipeline trusted-image enforcement and runner/container network-egress
enforcement remain absent. Credential isolation is established only in the
recorded hardened-child and unprotected-ref sense; GitLab forks remain untested. - Cursor is off in the shipped default roster and exercised only by the four-seat
Candidate Canary. Nothing verifies that the pinnedcursor-agenthonours its
Shell(*)and write denies at runtime. - The mock critique stage emits no critiques, so the noise-to-FYI demotion is
exercised live only if a real panel produces a noise majority. Unit and golden
consensus tests cover it. - Posted summaries still carry no loss counters. The
confidencedefault is
covered by unit tests only. - The four-seat canary does not certify a real run of the shipped three-seat
default roster. - Effort routes other than the
lowdefaults, including the 2.0.2 routes that
Migration restores, are not verified on this release's image pair.
Operator sign-off items
Final-pair provenance, real four-seat panels and critiques on both platforms, both
lifecycle campaigns, hostile containment and cleanup passed in Candidate Canary
39124481046. The default effort routes are taken from that run's GitHub panel; no
separate three-seat smoke ran. CI and image publication for R passed. Demo
preflight passed before and after the campaign.
The release PR also requires full quality and green final-head CI before merge.
The signed certificate and publication checks follow the Tagging procedure above.
No exact-value credential scan or OpenRouter billed token/cost inspection was
performed. Provider-internal effort behavior and non-default effort routes remain
outside the scoped pass.
Finalization
After every required gate passes, make release-repin RUN=<id> and
make release-finalize RUN=<id> EVIDENCE="<all record filenames>" prepare the
pins, active inputs, CHANGELOG promotion, and final notes together for one release
PR. Include quoted WAIVE arguments for every registered waiver. Scope and
Migration remain operator-written. After merging, generate the manifest and
certificate for the final merged P, sign and push the tag locally, and verify
publication. Then make release-open-next V=2.1.0 opens the next draft.
Historical inputs remain available at v2.0.3:release/release-inputs.json.
Code Tribunal 2.0.2
Code Tribunal 2.0.2
Release identity
- Release:
2.0.2 - Tag:
v2.0.2 - Release inputs:
release/release-inputs.json,status: active - Runtime source
R:3db908f06d141d23de99e7578ae5b5482ebaa498 - CI run:
37233827873 - Image publication run:
37233827865 - Base image:
ghcr.io/seanleecoder/code-tribunal/ai-review-base:2.0-3db908f06d141d23de99e7578ae5b5482ebaa498@sha256:2f3ffaba159e067825d72e889872ac6479bb31461943b6d86516a266e1faf3e9 - Reviewer image:
ghcr.io/seanleecoder/code-tribunal/ai-review-reviewer:2.0-3db908f06d141d23de99e7578ae5b5482ebaa498@sha256:7c59447733e5b6640f7ff759ab879c4682310054de130515841e91389a9b2447
Scope
This compatible patch updates the reviewer CLIs and Python/tooling dependencies,
refreshes the default roster to Claude Haiku 4.5 / medium, GPT-6 Luna / low,
and MiMo-V2.6-Flash with absent effort, and selects Composer 2.5 for the disabled
Cursor seat. It preserves one review and one critique round and the deterministic
informational consensus policy.
Finding grouping, documentation checks, and packaged smoke loading are simpler.
Release validation now preserves handwritten notes, binds evidence to source and
image digests, validates GitLab pins structurally, and verifies signed-tag
publication in an isolated checkout.
The unreleased S05 cutover (#171) and internal follow-up (#172) are reverted.
Artifacts retain finding_batch.v1, critique_batch.v1, consensus.v2, and the
previous pooled and model-authoring formats. Configuration remains
review_config.v3; persisted state and render-body.v4 are unchanged. SPEC-41
remains open, and S05 is deferred to separately planned major-release work.
Migration
Adopt the synchronized templates and digest-pinned image pair together. Existing
2.0 configuration and persisted state need no schema migration. Generate fresh
review and critique artifacts with the matched pair.
For MiMo, remove or blank stale AI_REVIEW_OPENCODE_EFFORT overrides so the
packaged configuration's absent effort applies. To clear a nonempty effort in a
custom YAML configuration, set AI_REVIEW_OPENCODE_EFFORT=unset. Missing or blank
model/effort overrides inherit YAML; a model-only override retains that YAML
seat's effort. Claude and Codex effort overrides also accept unset.
See effort inheritance and clearing
and upgrade operations.
Live campaign
| Record | Result |
|---|---|
| record-candidate-canary.md | Passed |
| record-github-current-image.md | Passed |
| record-gitlab-current-image.md | Passed |
| record-gitlab-hostile-mr.md | Passed |
| record-github-default-model-smoke.md | Passed |
| record-model-effort-routes.md | Passed |
| record-github-revision-failures.md | Registered waiver; reason in release inputs |
Release gates
- Run the scoped campaign against one frozen runtime source
Rand the final
base/reviewer pair. - Record only sanitized evidence; keep private consumer coordinates out of the
public repository. Audit withscripts/scan_evidence_leaks.pyand record its
exact scope. - Activate the release inputs only after every non-waived release-gating record
binds to the same source and image digests.
Tagging
The external manifest binds release_commit and re-derives the R..P diff, so the
tag must point at a commit that satisfies it.
- Merge the single release PR with a merge commit. Check out that final merged
commit asP, then runmake release-manifest P=<full SHA>. - Inspect
R..P, the manifest, checksum, and generated tag certificate before
signing. Signv2.0.2locally on exactlyP, using the generated message. - The signed certificate's
Release-manifest-sha256binds the manifest bytes.
Any change of tag target requires rebuilding and revalidating the certificate. - Push the signed tag and verify automatic publication of these notes and both
assets. CI never holds the signing key.
Carried known limitations
- Confidence remains required by the restored finding contract. Omission can
discard otherwise valid findings; posted summaries do not expose those loss
counts. SPEC-41
remains open. - In-pipeline trusted-image enforcement and runner/container network-egress
enforcement remain absent. Credential isolation is established only in the
recorded hardened-child and unprotected-ref sense; GitLab forks remain untested. - Cursor is disabled in the shipped default roster and exercised by the four-seat
Candidate Canary. MiMo Pro and Grok supplemental runs do not certify Flash or
the final release pair. - Earlier 2026-10-04 model smokes exercised the newer unreleased artifact contract
and remain supplemental evidence. Fresh final-pair evidence must certify the
restored 2.0 contract.
Operator sign-off items
Final-pair provenance, real panels and critiques on both platforms, both lifecycle
campaigns, hostile containment and cleanup passed in Candidate Canary 37234182540.
The separate GitHub three-seat smoke 37234212093 passed, including multiple
sequential MiMo tools, structured review/critique, and default effort routes.
Runtime quality passed with 1,098 tests and one skipped; final-head runtime PR CI
and image preflight passed before merge. Demo preflight passed after cleanup.
The release PR also requires full quality and green final-head CI before merge.
The signed certificate and publication checks follow the Tagging procedure above.
No exact-value credential scan or OpenRouter billed token/cost inspection was
performed. Provider-internal effort behavior and non-default effort routes remain
outside the scoped pass.
Finalization
After every required gate passes, make release-repin RUN=<id> and
make release-finalize RUN=<id> EVIDENCE="<all record filenames>" prepare the
pins, active inputs, CHANGELOG promotion, and final notes together for one release
PR. Include quoted WAIVE arguments for every registered waiver. Scope and
Migration remain operator-written. After merging, generate the manifest and
certificate for the final merged P, sign and push the tag locally, and verify
publication. Then make release-open-next V=<next> opens the next draft.
Historical inputs remain available at v2.0.2:release/release-inputs.json.
Code Tribunal 2.0.1
Code Tribunal 2.0.1
Release identity
- Release:
2.0.1 - Tag:
v2.0.1 - Release inputs:
release/release-inputs.json,status: active - Runtime source
R:c525ccff5e90beab8f498410dd4e3fe36ce10031 - CI run:
36982113841 - Image publication run:
36982113862 - Base image:
ghcr.io/seanleecoder/code-tribunal/ai-review-base:2.0-c525ccff5e90beab8f498410dd4e3fe36ce10031@sha256:6f2715a62bbdfe19a228848644ddef2fedcef17c4e769ac9b3c3775a16ecfe47 - Reviewer image:
ghcr.io/seanleecoder/code-tribunal/ai-review-reviewer:2.0-c525ccff5e90beab8f498410dd4e3fe36ce10031@sha256:1ee0b432fcedfc0e8bba11269f8cb2f410cfbe912ece808b54949dcff38cf8aa
Scope
- Release preparation is now one evidence-and-pin PR. The canary owns image identity, selectable zero-token lifecycle and hostile campaigns generate their own records, and release commands produce active inputs, final notes, CHANGELOG, and certificate assets through the existing validators.
- Pushing the locally signed tag publishes final notes and manifest assets after signature, main-history, and checksum verification. CI has no signing key.
- Failed accepted resolve/reopen commands fail
postwithpartial_failed, preserve the prior disposition, and allow a later retry. Findings remain informational. - Current documentation checks catch missing concrete repository paths and test definitions during ordinary PRs.
- The obsolete
ai_review_gatereservation is removed (COMPAT-005).
Migration
No configuration schema, artifact schema, posted-body format, model default, or supported platform changes. Consumers should adopt the synchronized template and image pair together. Automation that ignored accepted command failures now receives a failing post exit and should retry after fixing the platform error. The existing 1.x-to-2.0 migration still applies; see operations.
Live campaign
| Record | Result |
|---|---|
| record-candidate-canary.md | Passed |
| record-github-current-image.md | Passed |
| record-gitlab-current-image.md | Passed |
| record-gitlab-hostile-mr.md | Passed |
| record-gitlab-body-refresh.md | Passed |
| record-model-effort-routes.md | Registered waiver; reason in release inputs |
| record-github-revision-failures.md | Registered waiver; reason in release inputs |
Release gates
The required generated records and manual GitLab body-refresh record bind to the same runtime source and digest pair. The full canary proves the four-seat panel, both lifecycle surfaces, hostile credential withholding, and image provenance. Unchanged effort-route and GitHub prepare-race paths use explicit registered waivers; reasons appear only in release inputs.
Tagging
The locally signed tag targets the final merged release commit P. Its certificate contains Release-manifest-sha256, and the tag-push workflow rebuilds and validates the external manifest before publishing.
Carried known limitations
- GitLab does not enforce trusted images or composition inside the consumer pipeline. Containment rests on protected credential withholding and the out-of-band auditor; SPEC-43 remains open.
- Network egress is unenforced at the container and runner boundary.
- Credential isolation is established only for the recorded hardened-child, unprotected-ref topology. GitLab forks remain untested.
- Cursor is off in the default roster, and nothing proves that the pinned CLI honors its deny policy at runtime.
- The four-seat canary does not certify a real run of the shipped three-seat default roster.
- FYI-only posting, inline-unmappable summary fallback, and visible moved-comment re-anchoring retain their documented evidence gaps.
Operator sign-off items
- Both demos passed read-only preflight before the campaign.
- Full canary
36988314788exercised real four-seat review and critique on both platforms. The first attempt36978347766failed on a GitLab polling timeout and a malformed Cursor critique ID; its records were rejected. #154 fixed bounded GET polling before freezing the final source. - Image publication
36982113862retried its failed GHCR push using the same preflighted artifact; the successful attempt supplied the exact certified subjects. - The configured SSH public key matches the repository trusted signer and is registered as a GitHub signing key. GitHub reports
v2.0.0as verified after registration. - The preserved GitLab note refreshed in place with one update, zero creates, and unchanged identity; demo cleanup and read-only preflight passed.
- Signing remains a local operator action; no private key is supplied to CI.
- Demo consumer repinning is post-release hygiene and outside the promotion path.
Finalization
The activated inputs are retained at v2.0.1:release/release-inputs.json. The published external manifest and checksum bind the release commit to its runtime source, image pair, run IDs, evidence, and waivers.
Code Tribunal 2.0.0
Code Tribunal 2.0.0
Release identity
- Release:
2.0.0 - Tag:
v2.0.0 - Release inputs:
release/release-inputs.json,status: active - Runtime source
R:71dfabcae4d0ae459c10c1a9e1c809b3f8119c1f - Base image:
ghcr.io/seanleecoder/code-tribunal/ai-review-base:2.0-71dfabcae4d0ae459c10c1a9e1c809b3f8119c1f@sha256:f7028a5a22a2df0edd53235f3836b9adae3dbea474f711aab38b21b337181f02 - Reviewer image:
ghcr.io/seanleecoder/code-tribunal/ai-review-reviewer:2.0-71dfabcae4d0ae459c10c1a9e1c809b3f8119c1f@sha256:292142b70c96fbb9fda530eeafb79644694f23cae9e971a2ca3c74ac6b72295c - Quality run:
36312633166(passed) - Publication run:
36312633309(passed) - Image tag series:
2.0(2.0-<R>), replacing the1.0-<R>series
For the accepted release-version grammar and derived notes path, see the
release version contract.
Scope
- Findings are informational; the merge gate is gone. A finding surfaces as a
thread when two independent reviewer identities support it across review and
critique. Severity is an impact label only. Thegate(GitHub) and
ai_review_gate(GitLab) jobs, their schemas, CLI, andout/gate/artifact are
removed.postis the terminal job and fails only on a publication failure. - New configuration contract,
review_config.v3. It has one roster of three or
four seats selected withAI_REVIEW_REVIEWERS, fixed trusted adapter, credential,
and endpoint routes, and independent review and critique timeouts. Retired
overrides are rejected with migration guidance. Areview_config.v1document,
which every 1.x release shipped, is rejected once with the complete list of
removed keys. - New artifact and body formats.
consensus.v2replacesconsensus.v1.
render-body.v4replacesrender-body.v3with aSupport:footer, and
existing threads receive one cosmetic update.code_tribunal.release_inputs.v2
drops the redundanthashesobject. - Cursor is a peer seat. It is still off in the default roster because of its
separate credential and egress path. On GitHub it receivesCURSOR_API_KEYonly
whenAI_REVIEW_REVIEWERSnames it. - GitLab matrix jobs. Review and critique are one four-seat parallel matrix
apiece. - Refreshed runtime. The image pins Claude Code 2.1.283, Codex 0.157.1,
OpenCode 1.18.32, and Cursor Agent 2026.09.26-dd393fe, on Python 3.14 and
Debian Trixie. The reviewer image no longer ships Node, npm, or npx. - Candidate Canary. A protected, manually dispatched four-seat campaign on both
demo consumers now gates promotion of a candidate image pair. - Compatibility debt retired. COMPAT-003 (the split GitLab token wording) is
removed. COMPAT-001 and COMPAT-005 are retargeted to the first release after
2.0.0, and COMPAT-002 now coversreview_config.v1. - Candidate fixes found by the release campaign. A critic that miscopies a
pooled finding id now loses only that critique instead of failing consensus for
the whole run (#131). The GitHub canary executes its review panel once per
campaign whatever the demo'sAI_REVIEW_MANUALsetting (#132). Both were found
by the first candidate,d42559a, and fixed before the final runtime was frozen.
Version decision. 2.0.0 is a semver major. Removing the gate checks, the
review_config.v3, consensus.v2, and render-body.v4 contracts, and the
rejected variables all break 1.0.x consumers that do not migrate.
Migration
Follow Upgrade from 1.0.x to 2.0.
In short:
- Remove the required
gatecheck from branch protection or rulesets first. - Delete the rejected
AI_REVIEW_*_ENABLED,AI_REVIEW_MERGE_GATE_ENABLED, and
AI_REVIEW_STATE_BACKENDvariables. - Select at least three seats with
AI_REVIEW_REVIEWERS. - Migrate custom configuration to
review_config.v3. - Update the template and both images together.
- Move
consensus.jsonconsumers toconsensus.v2.
The CHANGELOG Migration table lists every retired surface.
Live campaign
Scoped with the
change-impact triage table
against git diff v1.0.2..R. The diff touches every impact set, so every
release-gating row re-ran live against the final pair:
| Row | Why it had to re-run | Record |
|---|---|---|
| Image publication verification | digests always change | docs/evidence/record-image-publication-verification.md — passed |
| Real four-seat panel, both platforms | adapters, reviewers, and config changed | docs/evidence/record-candidate-canary.md — passed; Candidate Canary run 36313164907 (GitHub PR #23, GitLab MR !21) |
| GitHub Chain B lifecycle | posting, rendering, anchors, and state changed | docs/evidence/record-github-current-image.md — passed; PR #25, adding fixture, create through stale head, blocker leaves the PR mergeable |
| GitLab Chain B lifecycle | the same, on an independent render surface | docs/evidence/record-gitlab-current-image.md — passed; MR !22, adding fixture, create through reopen, blocker leaves the MR mergeable |
render-body.v3 → v4 refresh |
the posted-body format changed | docs/evidence/record-render-body-v4-refresh.md — passed; GitHub comment 3650942127, one in-place update |
| GitLab hostile-MR boundary | input_bundle.py, platform/gitlab.py, pipeline_trust.py, and the template changed |
docs/evidence/record-gitlab-hostile-mr.md — passed; MR !23, all three protected secrets withheld |
Rows shipping under a registered waiver:
| Row | Waiver reason (matches verification.evidence_waivers verbatim) |
|---|---|
| GitHub revision failures | input_bundle.py was refactored into one bound-revision pipeline, but GitHub's three SHA checks and the HTTP 406 path are unchanged and covered by the SPEC-34 cases in test_input_bundle.py and test_github_platform.py; the stale-head boundary was reproduced live in record-github-current-image.md step 7, and the other race windows are milliseconds wide and not reproducible live. |
| Model effort routes | Model and effort defaults in config/review.yaml are unchanged since v1.0.2 (only comments changed) and no effort profile changed; the Candidate Canary exercised shipped default effort on all four seats (record-candidate-canary.md), so the non-default max/xhigh route checks were not rerun. |
The first candidate (R = d42559a, canary run 36113026891) failed on GitHub
when a critic miscopied a pooled finding id and consensus exited 3. That attempt
also exposed a duplicate GitHub panel run. #131 and #132 fixed both, #133
refreshed dependency pins, and only the rebuilt pair above was used as release
evidence.
Release evidence outcome
- Every re-run row passed against one frozen
Rand one image pair; two rows ship
under the registered waivers above. - Downloaded canary summaries, lifecycle post artifacts, and hostile-MR traces were
clean under the repository's ten pattern and entropy credential detectors.
High-entropy hits were inspected with values masked and were a GitLab runner
feature-flag name and a PR state-note payload, not credentials. An exact-value
audit was not performed and is not claimed. - The external release manifest binds the signed tag's release commit to
R, the
canonical-template hashes, the immutable digests, run IDs, evidence records, and
waivers.
Carried known limitations
- GitLab does not enforce the trusted image or trusted composition inside the
consumer pipeline. The 2.0.0 hostile probe again ranprepareon an
attacker-chosen image; containment comes from protected credential withholding
plus the out-of-band trust auditor (SPEC-43 remains open). - Network egress is not enforced at the container or runner boundary.
- "Credential isolated" is claimable only in the recorded hardened-child,
unprotected-ref topology. GitLab forks remain untested. - Cursor is off in the default roster. The canary exercised it with the demo's
pinnedcomposer-2.5, notauto, and nothing verifies that the pinned CLI
honours its deny policy at runtime. - The shipped three-seat default roster was not itself exercised by a real panel;
the canary ran all four seats. - A failed thread resolution is only a
post_resultwarning, so an expired GitHub
resolve token leaves green runs while/ai-review wontfixnever sticks. Observed
during this campaign and recorded, not changed.
Operator sign-off items
- Candidate Canary green on both platforms before any consumer repin: satisfied.
- Demo consumers repinned: GitHub adoption PR #24 (merged
b44ab38); GitLab
templatef8ae213with both consumer includes repointed. - The GitHub demo's classic branch protection still required the retired
gate
check and was removed by the operator, per the upgrade guide. The demo's
AI_REVIEW_GITHUB_RESOLVE_TOKENhad expired and was rotated during Chain B. - The GitLab refresh of the 1.0.0-format note
3601861614was not run. - Exact-value credential scan not performed; pattern and entropy scans passed.
v2.0.0is SSH-signed and verified before publication.
Release artifacts
The GitHub release publishes the external release manifest and its SHA-256
checksum. The activated inputs remain available at
v2.0.0:release/release-inputs.json.
Code Tribunal 1.0.2
Code Tribunal 1.0.2
Release identity
- Release:
1.0.2 - Tag:
v1.0.2 - Release inputs:
release/release-inputs.json,status: active - Runtime source
R:54dffa130be5c921602f264a2123fda4b1895f13 - Base image:
ghcr.io/seanleecoder/code-tribunal/ai-review-base:1.0-54dffa130be5c921602f264a2123fda4b1895f13@sha256:960600d339a9c7ed95539fe5de6f2414ed82fb06b96a02ed267d9332cd3d7fb4 - Reviewer image:
ghcr.io/seanleecoder/code-tribunal/ai-review-reviewer:1.0-54dffa130be5c921602f264a2123fda4b1895f13@sha256:6bf8fdfbe11a3b85519ae954411b436e5bed5f895e900074404a7b27359e6fab - Quality run:
31369496045(passed) - Publication run:
31369496025(passed)
For the accepted release-version grammar and derived notes path, see the
release version contract.
Scope
Carried in from the 1.0.1 release, which surfaced them:
- Release-tooling test fixes.
test_release_tools.pyasserted that the
checked-in release artifact is always an unbound draft, and hardcoded the release
version in its manifest tests. The first mademake qualityfail on any release
commit; the second made it fail on every post-release draft reset. Both are fixed:
the repo-state guard is now scoped by declared status, and the version is derived
from the artifact. This is why the 1.0.1 release commit shipped with two known
failing tests. - Stop shipping test code in the runtime image — done.
base.Dockerfilenow copies
onlyai-review/tests/fixtures, which is all preflight resolves paths from, and the
build-time in-image suite is removed. Both preflights instead bind-mount the
checkout's tests into the built image, which still proves "this exact image passes the
suite" and proves it against the current tests rather than whatever was frozen into
the layers. A production image that processes untrusted diffs and model output no
longer carries test code, and a change to test code no longer alters image
identity. Fixtures are the exception and still ship, because the reviewer preflight
runs--read-onlywith no mount and resolves its diff and repo from them; a fixture
change therefore does alter the image digest and stays part of the release binding.
The GitLab image-build template is removed entirely (see below), so the only image
build that remains is the GitHub publish workflow. - Removed the GitLab image-build template.
ai-review/ci/build-images.gitlab-ci.yml
built the product images from a GitLab mirror of this repository. No such project
exists, no current user-facing documentation referenced it, it was not part of the
hashed release artifact, and it was never executed against a real GitLab instance.
The historical Phase-2 acceptance record still references it and is retained as
written, with a superseded-procedure note added rather than its findings edited. Its
supply-chain guards incheck_supply_chain_pins.pyare removed with it. GitLab remains
a fully supported consumer platform —review.gitlab-ci.ymland
review-child.gitlab-ci.ymlare unchanged, still hashed incanonical_templates, and
still covered by the live evidence campaign. What is gone is only the ability to build
the images from GitLab; a consumer needing that would write their own pipeline around
base.Dockerfileandreviewer.Dockerfile. - Tag signing — established. SSH signing is configured and verified end to end
(Good "git" signature), with signers in.github/allowed_signersand the procedure
documented in
release-process.md. Applies from
v1.0.2;v1.0.0andv1.0.1remain unsigned and are not being retagged.
Also included in this release:
- Reliable OpenCode structured output. The adapter now uses OpenCode's
schema-backedStructuredOutputtransport through a loopback client, treats only
answer parts as answer text, rejects ambiguous JSON streams across every adapter,
and retains redacted raw stdout when parsing fails. If OpenCode returns an exact
JSON-stringified finding or critique inside the schema-backed array, the client
decodes that one unambiguous object; other malformed shapes remain fail-closed. A
provider-free image preflight exercises the complete transport, including its
permission negative control. - Bounded OpenCode tool reach. The reviewer explicitly denies external-directory
access, resolves the packaged CLI and interpreter ahead of ambientPATH, and ships
a checksum-verified ripgrep so search never downloads an unverified executable at
review time. Image preflights verify the effective permissions and both pinned
binaries against decoys. - Four peer reviewer seats.
AI_REVIEW_REVIEWERSselects any roster of Claude,
Codex, OpenCode, and Cursor while preserving the shipped Claude/Codex/OpenCode
default. Thresholds are validated against the configured panel and clamped to the
selected seats without dropping corroboration below two. GitHub scopes
CURSOR_API_KEYto the Cursor matrix job only; Cursor remains disabled by default. - Independent review and critique budgets. Review stages default to 1,800 seconds
and critiques to 900 seconds, with separate CI ceilings and a capped compatibility
fallback for older configurations. OpenCode forwardsmaxeffort unchanged rather
than rejecting or silently remapping it. - Refreshed reviewer toolchain. The published image pins OpenCode 1.18.12, Claude
Code 2.1.221, Codex 0.146.0, Cursor Agent 2026.07.23-e383d2b, and ripgrep 15.1.0.
Deferred, deliberately not in 1.0.2:
- SPEC-42 — whether a human
/ai-review wontfixmay clear the merge gate. Deferred
by decision. The current behaviour is unchanged and documented:wontfixdurably
dismisses a finding and suppresses re-posting, but consensus keeps counting it as
blocking and the required check stays red. Reproduced live again at 1.0.1. The only
escapes remain disablingmerge_gate.enabledor removing the required check.
Version decision. This ships as 1.0.2. The new reviewer roster is opt-in, the
shipped three-seat default and existing per-seat controls are unchanged, and the
remaining product changes are compatible fixes and operational hardening. Removing
test code changes image identity but not the supported runtime interface. The release
therefore keeps the already-reviewed patch target rather than reopening the train as a
minor release.
Live campaign
Scoped with the
change-impact triage table
against git diff v<previous>..R. Rows re-run live:
| Row | Why it must re-run | Record |
|---|---|---|
| Image publication verification | digests always change | docs/evidence/record-image-publication-verification.md — passed |
| GitHub real default-model panel | config/review.yaml, adapter transport, and reviewer selection changed |
docs/evidence/record-github-default-model-smoke.md — passed; PR #14, run 31370873644, full three-seat panel, real findings posted, required gate blocked |
Rows shipping under a registered waiver:
| Row | Waiver reason (must match verification.evidence_waivers verbatim) |
|---|---|
OpenCode max effort route |
OpenCode max effort was already accepted in real runs on an operator-controlled project; those runs are operator attestation rather than source-bound public evidence, and the final runtime change only normalizes a returned structured item after provider execution, so the operator accepted skipping a duplicate 1.0.2 rerun. |
| GitLab hostile-MR credential/enforcement boundary | Trust topology is unchanged: input_bundle.py, gitlab_platform.py, and scripts/verify_pipeline_trust.py carry no diff; roster documentation and stage timeouts do not alter credential withholding. Covered by test_verify_pipeline_trust.py and fork-secret withholding cases in test_input_bundle.py. |
| GitHub revision failures | github_platform.py and input_bundle.py carry no revision-race behavior change; covered by SPEC-34 cases in test_input_bundle.py and test_github_platform.py. |
The first candidate campaign (f21418f…, demo PR #12, run 31367545101,
attempts 1 and 2) reproducibly degraded because OpenCode returned a string item
that finalization dropped. That campaign is retained as failed validation. PR #116
closed the gap, runtime 54dffa1… and both images were rebuilt, and the final
campaign above reached panel_status: full with no failed reviewers.
Release evidence outcome
- The source-bound image-publication and GitHub default-model rows passed.
- OpenCode
max, the unchanged GitLab hostile-MR boundary, and unchanged GitHub
revision-failure wiring ship under the registered waivers above. - Downloaded final-campaign artifacts were clean under the repository's ten
pattern/entropy credential detectors. An exact-value audit was not performed and
is not claimed. - The external release manifest binds the signed tag's release commit to
R, the
canonical-template hashes, the immutable digests, run IDs, evidence records, and
waivers.
Carried known limitations
- GitLab does not enforce the trusted image or trusted composition inside the
consumer pipeline; the historical hostile-MR containment came from protected
credential withholding plus an out-of-band trust auditor. - Network egress is not enforced at the container or runner boundary.
- "Credential isolated" is claimable only in the recorded hardened-child,
unprotected-ref topology. GitLab forks remain untested. - Cursor is disabled by default and is not accepted for enablement until the
SPEC-21 closure checklist has a pinned Composer model and fresh denial evidence. - OpenCode
maxhas operator-attested real-project vali...
Code Tribunal 1.0.1
Code Tribunal 1.0.1
release/release-inputs.json is status: active and the scoped live-evidence
campaign is complete. These notes are final when v1.0.1 is tagged.
Release identity
- Release:
1.0.1 - Tag:
v1.0.1 - Runtime source
R:5817e99f8d831a816056feb2dfd44fac85b5196c - Release commit
P: see the annotated tagv1.0.1 - Publication run:
30536734285; quality run forR:30536734260 - Base image:
ghcr.io/seanleecoder/code-tribunal/ai-review-base:1.0-5817e99f8d831a816056feb2dfd44fac85b5196c@sha256:657d5e700768f29e98a980bf6264891d870b8e90af22ab9bd6c82beb30e27e03 - Reviewer image:
ghcr.io/seanleecoder/code-tribunal/ai-review-reviewer:1.0-5817e99f8d831a816056feb2dfd44fac85b5196c@sha256:a4b35e46ac23881e1a4dca52d2cf6a04ee77378d519706f43e70271f0d54cb0d - External manifest: build with
python scripts/build_release_manifest.py --tag v1.0.1 --runtime-source "$R" --release-commit "$P" --out /tmp/release-manifest.json
then validate withpython scripts/check_release_manifest.py /tmp/release-manifest.json
For the accepted release-version grammar and derived notes path, see the
release version contract.
Scope
This patch release carries the post-1.0.0 fixes and release-readiness work.
- Added/deleted-file anchor fix. The shipped 1.0.0 runtime dropped every
finding on an added or deleted file (and on any file ordered after one in the
diff) on GitHub, because the prepared diff's--- /dev/nullsentinel failed
anchor-scan path validation; consensus then exited 3 andpost/gatenever ran.
Anchor finalization now maps the added/deleted sides, so such findings are
accepted. This closes the defect knowingly shipped in 1.0.0. render-body.v3posted output. Free-text and path-shaped model values render
as literal data, malformed suggestions stay visible as data, and fragment-aware
truncation keeps spans atomic, blocks closed, and trusted footers/markers intact.
Prose now wraps instead of scrolling: bodies, evidence, and critique rationale
render as one code span per line rather than atextfenced block, while
suggestions keep the fenced block because they are code. Every model-authored
value still renders inside acodeorpreelement, which is also the boundary
keeping model text away from both platforms' post-render autolink, mention, and
issue-reference filters. Consensus artifacts remainconsensus.v1.- Reviewer model and effort defaults. Model IDs in
review.yamlmust fully
match the supported grammar; a malformed value, including a trailing newline, is
rejected withmodel_errorbefore the reviewer CLI is invoked. The Cursor
permission smoke now requires an explicit exact model and rejects the discovery
placeholderautobefore invoking Docker. - Release-state tooling. Prose claims about release state are now bound to
release-inputs.statusand enforced inmake quality; live evidence moved to
docs/evidence/;scripts/scan_evidence_leaks.pyreplaces ad-hoc credential
greps.
Migration
The posted-body format is render-body.v3. Existing bot-authored inline threads
receive a one-time body update on the next review run; issue IDs, state records,
and marker grammar are unchanged. Deployments tracking main before this change see
one further refresh, because the prose format changed within v3.
Cursor
The Cursor CLI remains an opt-in substitute reviewer with a separate credential and
egress path. Completing SPEC-21 Cursor acceptance
is required before enabling Cursor, not before shipping 1.0.1. The historical
1.0.0 Cursor runs do not certify Cursor enablement.
Live campaign
Scoped with the
change-impact triage table
against git diff v1.0.0..R. That diff touches anchors.py, render.py, post.py,
schema.py, types.py, mock_reviewer.py, adapter_runner.py, config/review.yaml,
consensus.schema.json, and base.Dockerfile. It leaves input_bundle.py,
github_platform.py, gitlab_platform.py, gate.py, consensus.py, and
scripts/verify_pipeline_trust.py unchanged — which is what makes the waivers
below honest rather than convenient.
Rows re-run live:
| Row | Why it must re-run | Record |
|---|---|---|
| Image publication verification | digests always change | record |
| GitHub lifecycle Chain B, adding fixture | anchors.py/post.py/render.py changed, and the added-file path has never had a live green run. Step 1 asserts accepted_finding_count == raw_finding_count |
record |
| GitLab lifecycle Chain B, condensed | independent render surface for render-body.v3; create, changed-body in-place update, blocking gate |
record |
| One real 3-model panel, GitHub only | default model IDs and the tightened model-ID grammar changed; only a real provider call proves they resolve | record |
render-body.v3 refresh of a pre-v3 thread |
the only live proof of the migration claim above; re-review a change request whose bot thread predates v3 | folded into the lifecycle records as a labelled step |
The GitLab real panel is not run: the adapter path is platform-independent, and the
single GitHub panel proves the changed defaults resolve.
Rows shipping under a registered waiver. Each carries a Release-evidence-waived
line whose text is registered verbatim under verification.evidence_waivers; both
halves were stamped at activation, because the artifact must carry an empty
verification block while it is a draft:
| Row | Basis |
|---|---|
| GitLab hostile-MR credential/enforcement boundary | credential withholding, prepare fail-closed, and trusted-composition auditing are unchanged between R(1.0.0) = 88bc941 and R(1.0.1); regression-covered by test_verify_pipeline_trust.py and the fork-secret withholding cases in test_input_bundle.py; passed live at 1.0.0 against the prior pair |
Codex max / OpenCode xhigh effort routes |
unvalidated at the real providers. Effort levels pass through without coercion, and a malformed model or effort value fails closed with model_error before the CLI is invoked, so a provider-side rejection surfaces as an adapter failure rather than silent degradation |
| GitHub revision failures (SPEC-34) | 1.0.0 waiver carried forward unchanged; github_platform.py and input_bundle.py are untouched and the row is already classified live-optional |
1.0.1 release gates
- Run the scoped campaign above against one frozen runtime source and the final
base/reviewer image pair. - Record only sanitized evidence and keep private consumer coordinates out of
the public repository. Audit withscripts/scan_evidence_leaks.pyand record its
exact scope, including the operator-only--exact-value-filepass that 1.0.0
left unmet. - Activate the release inputs only after every non-waived release-gating record
binds to the same source and image digests.
Correction to the 1.0.0 record
release/1.0.0.md is pinned byte-identical to its tag and must not be rewritten, so
this correction is recorded here instead. Its "Tagging" section names
0f86df6a6f698f44dd58f3007943786c0b90e528 as the commit to tag. That commit was
rewritten before the release PR merged and is not reachable from main. The released
release commit P is 3ad443e0b3d91f2736c3dd3b4f1fb5d7f8d21997, which is what
v1.0.0 actually tags; PR #85 landed as a true merge commit
(a9ec8c55fc2f716ac728f67644388ac546c6c89e) so P stayed in history. The tagging
constraint itself was followed correctly — only the SHA in the prose is stale.
Carried known limitations
Unchanged from 1.0.0 and not softened by this release: there is no in-pipeline
trusted-image or trusted-composition enforcement — a hostile consumer
.gitlab-ci.yml can substitute the pinned images, and containment comes from
credential withholding plus the out-of-band trust auditor. Network egress is
unenforced at the container/runner boundary. "Credential isolated" is claimable only
in the recorded sense — protected credentials withheld from an unprotected-ref MR in
the hardened child topology — and not as a product-wide property. GitLab forks are
untested. Cursor remains disabled pending the SPEC-21 enablement queue.
Cursor remains disabled for this release. Before enabling it, complete the
SPEC-21 checklist's explicit ask-mode decision and, if the chosen contract
requires Cursor-backed blocking findings, its blocking fixture and required-check
verification.
Finalization
The scoped campaign passed, the release inputs are active, and every cited record
binds to R = 5817e99 with the base and reviewer digests above. Remaining: tag
v1.0.1 on release commit P, then attach the external manifest and its checksum to
the GitHub release. See "Tagging" below — the tag target is constrained.
Tagging
The external manifest binds release_commit and re-derives the R..P diff, so the
tag must point at a commit that satisfies it.
- Do not squash-merge the release pull request. A squash rewrites
Pinto a new
commit and drops it frommain's history, which invalidates the manifest. - Either tag
v1.0.1onPexactly, or rebuild and re-validate the manifest ag...
Code Tribunal 1.0.0
Code Tribunal 1.0.0 — first stable release.
Release identity
Runtime source R |
88bc9412b283d4a44328ab3ffd9f9708b0290f8e |
Release commit P |
3ad443e0b3d91f2736c3dd3b4f1fb5d7f8d21997 |
| Publication run | 30125524008 |
| Manifest sha256 | b7570e173d86680998cfd77cff34d5c42de55f8e5cf57b4e17ea944744f02f7f |
Images (pull by digest, never by the mutable 1.0 tag):
ghcr.io/seanleecoder/code-tribunal/ai-review-base:1.0-88bc9412b283d4a44328ab3ffd9f9708b0290f8e@sha256:f2a433ac1094d45943a2973c334ff0d711d6aca73980cd44cfefe3aa0b403896
ghcr.io/seanleecoder/code-tribunal/ai-review-reviewer:1.0-88bc9412b283d4a44328ab3ffd9f9708b0290f8e@sha256:2fd84c43fc4529182bf077c809ba40bc6e628b5e77d6f1a2a0ffd24e902591fe
Both subjects are anonymously resolvable by digest, carry an OCI revision label equal to R, and have GitHub provenance attestations bound to the publication run above.
⚠️ Known defect: GitHub pull requests that add or delete files
On GitHub, findings can be dropped and the review can fail to complete when a pull request adds or deletes a file. GitHub renders an added file's diff with --- /dev/null, which anchor resolution rejects while scanning; affected findings are dropped, and when every seat is affected consensus exits 3, post/gate are skipped, and the required gate check cannot succeed.
- Triggers for a finding on an added/deleted file, or on a file ordered after one in the diff.
- Affects real reviewers, not only the deterministic mock. GitLab is unaffected.
- No state corruption; the failure is visible rather than silent.
- Workaround: land file additions in a separate change request from the code you want reviewed, or re-run once the added file has merged.
- Fix verified and scheduled for 1.0.1.
Detection symptoms are in release/1.0.0.md.
Live evidence
Release-gating evidence was re-run against this exact image pair:
| Row | Result |
|---|---|
| Image publication | passed — anonymous digests, revision labels, provenance attestations |
| GitHub lifecycle | passed — create, unchanged rerun, changed-body in-place update, resolve, persistence, reopen, stale-head no-op; required check genuinely blocked the merge |
| GitHub default-model smoke | passed — real three-seat panel, panel_status: full, four real security findings |
| GitLab lifecycle | passed — same lifecycle in the hardened child topology; "Pipelines must succeed" withheld the merge |
| GitLab hostile MR | passed — protected credentials withheld on an unprotected ref, prepare failed closed, empty input bundle, trust auditor rejected the hostile composition |
| GitHub revision failures (SPEC-34) | waived — non-gating and regression-covered; the stale-head boundary was reproduced live anyway |
The positive changed-body in-place update, previously never demonstrated live on either platform, is now proven on both.
Deployment posture — read before relying on isolation claims
- Trusted image pinning is not enforced in-pipeline. A consumer CI config can substitute the base/reviewer images by declaring them in its own top-level
variables:and enabling variable forwarding. This was reproduced live. Containment comes from protected-credential withholding plus the operator-runscripts/verify_pipeline_trust.py, which does reject such a composition — run it against your consumer config. - Credential isolation is evidenced narrowly: protected credentials withheld from a hostile MR on an unprotected ref in the hardened child topology. Not a product-wide guarantee. GitLab fork MRs untested; GitHub external forks are skipped by design.
/ai-review wontfixdurably dismisses a finding but does not clear the merge gate.- A reviewer that omits the required
confidencefield has all its findings dropped, which can silently degrade a panel. - Network egress is not enforced at the container/runner boundary.
- Cursor is experimental, has no evidence row, and is not evidence-backed.
Verifying this release
shasum -a 256 -c code-tribunal-1.0.0-release-manifest.json.sha256
python scripts/check_release_manifest.py code-tribunal-1.0.0-release-manifest.json
gh attestation verify \
oci://ghcr.io/seanleecoder/code-tribunal/ai-review-reviewer@sha256:2fd84c43fc4529182bf077c809ba40bc6e628b5e77d6f1a2a0ffd24e902591fe \
--repo seanleecoder/code-tribunalRollback means restoring the previous immutable template/image set, not moving a mutable tag. See docs/operations.md.
Code Tribunal 1.0.0-rc.1
Code Tribunal 1.0.0-rc.1
This release candidate publishes the 1.0 container/template distribution for
operator validation before the final v1.0.0 tag.
Release identity
- Runtime source
R:15d424feea730a04338ed423bf93b8797d807bbc - Release-candidate evidence branch commit: recorded in the
v1.0.0-rc.1tag - Base image:
ghcr.io/seanleecoder/code-tribunal/ai-review-base:1.0-15d424feea730a04338ed423bf93b8797d807bbc@sha256:28ddb7ed1c4e0986606011793c31955751df61ce2d25a0def0f47e1eecf97eee - Reviewer image:
ghcr.io/seanleecoder/code-tribunal/ai-review-reviewer:1.0-15d424feea730a04338ed423bf93b8797d807bbc@sha256:cba20164abaaad10a37ec6d27f17bf55662b70d32339830fba3092117dbe7a8d - Release inputs:
release/release-inputs.json, active for1.0.0 - Publication run:
29845398524 - CI validation run:
29845398459
Scope
- Supported distribution is the digest-pinned container images plus the GitHub
Actions and GitLab CI templates. - Python source imports remain an unsupported contributor/testing mechanism.
- Release-input validation, supply-chain pin checks, documentation checks,
mypy, unit/integration tests, and compilation passed on the RC evidence
branch before publication. - GitHub and GitLab exact-value secret audits were completed by the operator on
2026-07-21 without recording secret values in the repository.
RC known gaps
These gaps are accepted for 1.0.0-rc.1 and must be completed or explicitly
waived before final v1.0.0:
- GitHub oversized raw-diff HTTP 406 has not been exercised live. Unit coverage
verifies the fail-closed message and no-bundle behavior. - GitHub manifest-finalization head movement has not been hit live. Two
recorded live attempts missed the short finalization window and completed
successfully; unit coverage verifies the three-read stale-head path. - Some GitHub and GitLab lifecycle variants remain partial, including positive
changed-body in-place update and unrelated line movement behavior. - GitLab hostile-MR override/forgery variants remain partial, though protected
credential withholding, forwarding isolation, and symlink containment passed
against P0.
Upgrade
Pin CI templates to this tag and keep image references digest-pinned. Do not use
mutable image tags as the release identity.
GitHub users should require the gate check on protected branches if blocking
review findings must prevent merge. GitLab users should keep "Pipelines must
succeed" enabled for merge blocking.
Rollback
Rollback means restoring the previous immutable v0.4.0 template/image set, not
pulling a mutable tag:
- Template/tag commit:
v0.4.0at
203d22158b806cdb1288ebc55497c7e982777885 - Base image:
ghcr.io/seanleecoder/code-tribunal/ai-review-base:1.0-203d22158b806cdb1288ebc55497c7e982777885@sha256:5fb42d0f8a0397602411fca84e1d918850f3c84ea6392493b9a24197fa3fe181 - Reviewer image:
ghcr.io/seanleecoder/code-tribunal/ai-review-reviewer:1.0-203d22158b806cdb1288ebc55497c7e982777885@sha256:47d98f6b195408716e137b12a3118a2eee1d7042904f4c606d49f9316e5fb573
After rollback, rerun one representative GitHub or GitLab review flow and verify
the platform's merge gate behavior before treating the rollback as complete.
Verification
Run:
make PYTHON=.venv/bin/python quality
python scripts/check_release_inputs.pyThe final release-manifest.json is intentionally reserved for the final
v1.0.0 tag because the manifest tooling validates the final release tag
coordinate.
v0.4.0
Highlights
- Added a hardened GitHub Actions review path with runtime-selected GitHub posting and state backends.
- Moved platform adapter construction into a dedicated composition root.
- Enabled the GitHub merge gate by default.
- Removed inert configuration, spend-control, and issue-tracker surfaces.
- Improved acceptance evidence and archived completed or paused improvement plans.
Breaking changes and migration
Custom review configurations must remove the former top-level jira, budget, severity_order, and categories keys. Removed nested placeholders—including reviewer cli_version, panel/degradation metadata, posting marker/locking controls, declarative merge-gate settings, state marker versions, per-reviewer limits, and declarative security controls—must also be removed. Unknown keys are rejected at every active mapping level.
GitHub installations that require the previous advisory-only behavior must set AI_REVIEW_MERGE_GATE_ENABLED=false. The gate blocks merges only when its check is required by repository branch protection or rulesets.
See CHANGELOG.md for the complete change list.
Published images
- Base:
ghcr.io/seanleecoder/code-tribunal/ai-review-base:1.0-203d22158b806cdb1288ebc55497c7e982777885- Digest:
sha256:5fb42d0f8a0397602411fca84e1d918850f3c84ea6392493b9a24197fa3fe181
- Digest:
- Reviewer:
ghcr.io/seanleecoder/code-tribunal/ai-review-reviewer:1.0-203d22158b806cdb1288ebc55497c7e982777885- Digest:
sha256:47d98f6b195408716e137b12a3118a2eee1d7042904f4c606d49f9316e5fb573
- Digest:
Both images passed preflight and have GitHub artifact attestations.
Full comparison: v0.3.1...v0.4.0