v1.4.0
Indirect eval / outcome loop, reliable GitHub App multi-install gate reviews, PR status + republish, and per-finding SCM comments.
Added
- Automatic / indirect eval (outcome loop) — learn from what users and merges actually do:
- Merge webhooks (GitHub
closed+merged, GitLabmerge) enqueuejobKind=pr_outcome(no agent pipeline) - Classifies findings: accepted / fixed / thumbs_up / false_positive / dismissed / unaddressed_at_merge
- Mines agent-miss candidates on sensitive paths changed with no finding
- Gate regret: approve+critical open, or request_changes+only noise
- Durable
pr_outcomes+finding_outcomes(migration015_review_outcomes.sqlor file store) - 👍 creates positive preference memories (mirrors 👎 suppress)
- Preference bag-of-words embeddings filter in noise stack (near 👎 → drop)
- Analytics: split fixAcceptRate / noiseRate / openRate + confidence calibration
(GET /v1/analytics/address-rate,/v1/analytics/outcomes,/eval-export) - Offline eval harness consumes production outcome fixtures (
packages/evals) - Outcome consolidator — promote frequent merge outcomes to memories with correct scope:
repo-only common → repo memory; multi-repo or important (critical/high / gate regret) → org memory.
POST /v1/analytics/outcomes/consolidate; also runs after each merge outcome job.
Sourceoutcome_aggregate(auditable on Learnings). No longer writes a repo memory on every single accept. - Docs — GitHub App / GitLab webhook events for gate + merge outcomes (
docs/docs/configure/connectors.md, README). - GitHub
pull_request_review_thread— resolved/unresolved maps comment ids → findings (scmCommentId), writes
thread_resolved/thread_unresolvedoutcomes, soft status tags, consolidator feed. - GitHub
security_advisory(+ repository_advisory) — external GHSA →security_advisoryoutcome + soft pattern
memory for coverage / FN; optional org promotion when severity is high. - Manifest defaults include
pull_request_review_threadandsecurity_advisory.
- Merge webhooks (GitHub
- PR status comments — webhook-triggered reviews post a progress comment on the PR (“Reviewing / Re-reviewing now…”),
then update it on prepare failure, crash (exhausted retries), or successful completion so GitHub-only readers are not stuck. - Republish to PR — post findings for a finished gate session without re-running agents:
POST /v1/sessions/:id/publish(reviewer+)- Sessions UI drawer action Republish to PR
- Diff-aware inline comments + conversation fallbacks with full finding body (suggestion / proposed fix)
Changed
- SCM publish posts per-finding PR comments with UI-style bodies (severity, path, explanation, suggestion, proposed fix),
not only a summary review. Default cap raised to 40 findings (STEW_COMMENT_CAP). - Display brand in PR summary / gate check titles: Codesteward (not “CodeSteward”).
- Gate review jobs carry
headBranchfor clone/checkout of the PR tip (not base).
Fixed
- GitHub webhook redeliver — same
X-GitHub-Deliveryid is reprocessed afterprocessed/failed(or stale
received), instead of always returning{ duplicate: true }with no new session. Concurrent in-flight claims
still dedupe (~2 min,STEW_WEBHOOK_CLAIM_STALE_MS). - Multi-install GitHub App token pick — mint installation tokens for the repo owner (e.g.
scigility) instead of a
stale connectoraccountLogin: localinstall. Applied to webhook SCM, clone auth, check runs, publish, and republish.
Fixes clone “Repository not found”,getPullRequest404 on mentions, andpostReview404 after a successful review. - Workspace clone checkout —
git checkout --force -- <sha>treated the SHA as a pathspec and failed with
pathspec '…' did not match any file(s) known to git. Checkout now usesswitch --detach/checkout -f <ref>;
fetch fallbacks includepull/<n>/head, head branch, then object id. - PR review comments 422 “Line could not be resolved” — only attach inline comments to lines present in PR diff hunks;
other findings become conversation comments so they are not dropped when a batch fails. - Stuck “Re-reviewing now” comment — completion path now updates the status comment (and notes when SCM publish failed).
- Webhook delivery logging — outcomes (ignored reason, session/job ids, publish errors) written to logs / delivery row
so redeliver forensics is not silent.
Container images
docker pull ghcr.io/codesteward/codesteward:1.4.0
docker pull ghcr.io/codesteward/codesteward/ui:1.4.0
docker pull ghcr.io/codesteward/codesteward/keycloak:26.7.0 # tag = upstream Keycloak, not product 1.4.0App image runs API by default (SERVICE=api). Worker:
docker run --rm -e SERVICE=worker ghcr.io/codesteward/codesteward:1.4.0Keycloak image tags match upstream Keycloak (theme + realm baked in; no git mounts):
docker run --rm -p 8083:8083 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin \
ghcr.io/codesteward/codesteward/keycloak:26.7.0 start-dev --import-realm --http-port=8083Helm chart (OCI on GHCR)
helm install codesteward oci://ghcr.io/codesteward/codesteward/charts/codesteward --version 1.4.0
# or: helm pull oci://ghcr.io/codesteward/codesteward/charts/codesteward --version 1.4.0Chart package is also attached to this release as codesteward-1.4.0.tgz.
Docs: Kubernetes quick start in the product documentation site.
Images are signed with cosign keyless via GitHub OIDC.
Verify with:
cosign verify ghcr.io/codesteward/codesteward:1.4.0 \
--certificate-identity-regexp 'https://github.com/Codesteward/codesteward/.*' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com