All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
-
Slack, Discord and Telegram callbacks return a sanitized HTTP 409 when a delivery key is reused with different content instead of acknowledging it as a duplicate. Telegram enforces safe-integer IDs and preserves multiline command rejection; Discord snowflakes remain exact strings.
-
Slack Socket Mode bounds the full handshake through verified
hello, stops stale transports before reconnecting, drains pending handshakes, and sends an empty ACK after durable admission when response payloads are unsupported. -
Legacy and versioned reply outbox sends use owner/fence checks before POST, reject stale workers after lease expiry, retain uncertain outcomes, use credentials from the final config generation, retry pre-send failures, and emit notifications for retry-exhausted terminal states. PostgreSQL status lookups are cancellable, and GitLab
web_urlreceipts survive journal recovery. -
Slack and Telegram preserve balanced link parentheses, multi-backtick code tokens, uppercase HTTP schemes and Slack blockquotes during conversion and truncation. Managed consolidated issue bodies have a 65,536-unit budget with staged resolved-detail reduction and grapheme-safe excerpts; required fingerprint overflow fails before publication or closure.
-
Problem-resolution rejects valid verdicts duplicated by invalid entries in either order and includes initial and confirmation triage calls in the review's cumulative model budget. Zod 4 config parsing preserves nested defaults and rejects custom prototypes and explicit
__proto__keys. -
Git fetch no longer invokes the system credential helper when the adapter already supplies a token, preventing Git for Windows' interactive helper selector from blocking the run before agent startup. Repositories that rely on helper-provided credentials retain the existing behavior.
-
Docs site dev/preview servers now bind
127.0.0.1instead oflocalhost: on hosts where the resolver returns::1first, the default produced an IPv6-only[::1]listener that was unreachable wherever the IPv6 loopback is broken, so the printedhttp://localhost:4321URL never opened.
-
Updated workspace dependencies to the latest compatible releases, including Zod 4, Undici 8, OpenTelemetry 0.300 and Astro 7.4. TypeScript remains at 6.0.3 because the current typescript-eslint peer range excludes 6.1 and 7.x. Node.js is now
>=22.23.4; the rootpackageManageragain pins pnpm 10.20.0 to match CI and the deployment image. -
Refreshed the offline models.dev snapshot to 230 providers and 8888 models. The Kimi Coding preset now resolves through
kimi-code-plan-cnafter the upstream provider split, preserving existing model IDs and endpoint behavior. -
Docs site wide-screen layout: content column cap raised from 45rem to 96rem on docs pages and 120rem on the splash landing page so 2.5K/4K viewports are used, while running text stays capped at a 62ch prose measure (~62 Latin / ~39 CJK characters per line, within WCAG 1.4.8); tables, code blocks, and card grids keep the full column width, and full-width component boxes (Aside/Card/LinkCard) let their inner text fill the frame. The previous full-bleed experiment (100% width plus root font-size scaling) produced ~229-character lines at 2560px and is removed. Landing pages no longer duplicate the site title in the browser tab (
Home | AICodeReviewer/首页 | AICodeReviewer).
- Auto-commit batch per-target publication recovery: the
publication_pendingcheckpoint now carries the analysis payload plus per-channel receipts (pending/published/failed/unknown), so a resumed batch skips LLM/analysis, never re-calls channels with a confirmedpublishedreceipt, and only retries unfinished channels. Payload exceeding the checkpoint size cap degrades to full replay. The admin batches API returns each batch'spublicationsreceipts for operator inspection. - Config-example test sweep: every
yamlcode block in docs matching a config namespace is schema-validated, plus negative tests for type errors, unknown keys, forbidden keys, and trigger reference validation. - De-AI writing guidance for repository prose consolidated in
.agents/skills/ai-agent-maintenance/references/writing-guidance.md(current-version-only statements, bilingual banned-word lists, sentence and structure rules);docs-writing-styleand the bilingual site validator now point there.
- Publication recovery now fences each channel, persists receipts before continuing, retains analysis usage/cost, and keeps failures across later messages. Redis preserves checkpoint arrays; overflow removes stale snapshots and corrupt payloads fail closed. Config-example discovery no longer silently skips malformed YAML or mixed known/unknown root keys.
- Publish image workflow now creates the gitignored
deploy/docker-staticplaceholder before the Docker build (mirroringdeploy.sh), fixing tag builds that failed with"/deploy/docker-static": not found. - Vitest
testTimeoutraised to 15s: live-service suites exceeded the 5s default under full-suite worker load on many-core hosts, causing rotating flakes that passed standalone. - Timing-sensitive tests use fake timers or event gates instead of wall-clock sleeps: LLM gateway backoff/give-up cases assert exact timer ticks; runtime-config drain cases advance the fake 25ms poll loop; the stale-run-dir overlap case holds the first spawn until the second spawn call; the SQLite lock-TTL reclaim case advances the fake clock past the TTL; native sandbox kill cases wait for the grandchild's first heartbeat before the timeout cascade; the replica process matrix reaps orphaned postgres
--forkchildworkers after a forced kill and retries same-datadir restarts on the transient "pre-existing shared memory block is still in use" error (500ms interval, 60s deadline).
aicr.get_review_commitsandaicr.get_review_context: host-backed Git/SVN/P4 review queries, per-commit files/diffs, paginated file unions, optional authors and fork source/target metadata; native MCP state and JSON/stream follow-up paths share the implementation.review.pull_request.include_target_branches: receive-side target (base) branch allowlist for PR/MR analysis, layered global → workspace defaults → instance with wholesale replacement ([]clears back to all branches).ReviewEventgainstargetBranch, mapped from Gitea/GitHubpull_request.base.ref, GitLabtarget_branch, and comment-command PR-detailbase.ref; PRs/MRs targeting unlisted branches are ignored at receive time (webhook log decisionignored, reasontarget_branch_not_watched) with no run produced, events with an unknown target branch fail open, and push/issue/manual flows are never filtered.review.auto_commit.include_branches: receive-side branch allowlist for automatic commit events (push / P4 change-commit / SVN post-commit), layered global → workspace defaults → instance with wholesale replacement ([]clears back to all branches). Pushes to unlisted branches are ignored before receipt persistence (webhook log decisionignored, reasonbranch_not_watched); PR/MR/comment flows are unaffected and branchless P4/SVN hooks bypass the filter. The resolved list stays out ofpolicyVersion, so sealed receipts remain valid.- Dashboard Live tab: responsive worker cards with task/run identity, revision, phase, model, start/elapsed time, tokens, cache hit/miss/write counts, requests, retries/fallbacks, cost, and usage update time. Kilo/OpenCode and pi/omp report completed turns through advisory sandbox stdout callbacks. Refresh defaults to manual; optional polling is serialized, pauses when hidden, and marks failed snapshots stale. Execution IDs isolate overlapping attempts.
- Run VCS stamp:
review_runsgainsvcs_kindandhead_committed_at(migration009_review_run_vcs_stamp); the orchestrator resolves the head commit time via the new advisoryVcsAdapter.fetchRevisionCommittedAt(gitgit log --format=%cI, svnsvn log --xml, p4p4 -ztag describe -s), and the Overview recent-activity and Runs tables show branch + short revision (git short sha, SVNr<N>, P4CL <N>) + commit time. - GitLab webhook branch mapping: push events map
reftoReviewEvent.branchand merge-request events mapobject_attributes.source_branch. - M16:
review.pull_request.schedule— optional weekly execution window for PR/MR analysis (including comment review commands), same shape asreview.auto_commit.schedule, resolved across global/defaults/instance layers with wholesale replacement; falls back to the resolved auto-commit schedule when unset at all layers. - M16: Persistent deferral registry (
ReviewDeferralManager+review_deferralsstore table, migration008): webhook events arriving outside the execution window are persisted by dedup key and resume after a restart (claimed rows reset to pending); without the observability store deferrals fall back to in-process memory timers. - M16: Deferred comment review commands now post a reply on the PR/MR stating the scheduled start time (
bypassNoProblemsPolicy, once per deferral). - M16: Webhook event log (
webhook_eventsstore table, migration007, retention 100) recorded across all webhook processors with dispositions (processed/deferred/deduplicated/rejected/ignored/error), exposed viaGET /api/admin/eventsand a new Dashboard Events tab (20 per page). - M16: Dashboard Overview recent-activity table gains a Tokens column (total tokens + cache hit rate).
- M8: OTel OTLP HTTP trace exporter configuration in
@aicr/core(createOtelSdkreadsOTEL_EXPORTER_OTLP_ENDPOINTandOTEL_EXPORTER_OTLP_HEADERS). - M8: Prometheus metrics endpoint (
/metrics) with counters (aicr_reviews_total,aicr_reviews_skipped_total,aicr_reviews_failed_total,aicr_problems_total) and histogram (aicr_review_duration_seconds). - M8: Run snapshot persistence to
runs/<run_id>/run.jsonviasaveRunSnapshot, configurable throughServerAppOptions.runsDir. - M9:
docker_socketfactory test confirming it maps to the docker backend implementation. - M9:
k8s_podandfirecrackersandbox backend skeletons with descriptive error messages. - Docs: Podman rootless
invalid internal statustroubleshooting guide indocs/podman.md. - Docs: Test environment isolation guidelines in
development/README.md. - M9: Sandbox backend capability matrix documented in
docs/ai/architecture.md§3.8.1 (native,docker,podman,docker_socket,k8s_pod,firecracker). - M9:
docker_socketconfiguration example added toexample/README.md. - M9: Release checklist created at
docs/ai/milestones/M9-checklist.md. - M5: Kilo Code end-to-end acceptance verified via production log analysis (agent sandbox execution, MCP state file read, stdout stream parsing, structured output conversion all confirmed working).
- M6: GitHub production e2e verified (
github-atframework/github-owenttriggers running, auto-created issues and PR analysis records confirmed). - M8: OTel SDK now wired into
aicr servecommand; starts automatically whenOTEL_EXPORTER_OTLP_ENDPOINTis set. - M8:
aicr evalCLI command added — runs evaluation benchmarks fromeval/directory JSON fixtures against configured LLM, outputs structured pass/fail summary. - M8: Baseline eval fixture
eval/baseline-sql-injection.jsonadded as a seed test case. - M8: Eval fixtures expanded to 6 total covering security (SQL injection, hardcoded secrets), correctness (null dereference, silenced errors), style (naming convention), and performance (N+1 query pattern).
- M7:
review.output_languagenow injected into the review task context asOutput language: <lang>directive when set to a non-English value (packages/server/src/review-orchestrator.ts,packages/server/src/bootstrap.ts). - M7: Barrel export tests added for
@aicr/core,@aicr/cli,@aicr/server,@aicr/llm,@aicr/vcs,@aicr/outputs,@aicr/mcp-output,@aicr/store(each package now hastest/index.test.tsverifying exports per AGENTS.md pitfall #10). - M9:
deploy/deploy.shnow includes--storage-driver=overlayon allpodmancommands and a preflightpodman system migratecheck (addresses rootless Podman 5.x storage corruption). - M9:
.dockerignoreadded to reduce Docker build context size. - M9:
deploy.shconverted to use environment-variable overrides (AICR_DEPLOY_DIR,AICR_IMAGE_NAME,AICR_HOST_PORT,AICR_CONTAINER_NAME,AICR_ENGINE) instead of hardcoded paths. - M9:
deploy/Caddyfile.exampleadded as a sample reverse proxy configuration for TLS termination. - M9:
deploy/Dockerfilenow copiessandboxandevalnode_modules for forward compatibility. - Docs:
example/README.mdP4 authentication table row corrected — P4 uses server API key, not webhook HMAC. - Docs:
example/.env.sampleupdated with missing env vars (AICR_WORKSPACE_API_KEY, GitHub multi-profile, Feishu issue notification). - Docs:
example/config.yamlqueue section updated with commentedrate_limit,retry,dead_letterexamples. - Docs:
.agents/skills/remote-deployment/SKILL.mdenv var names aligned withexample/.env.sample.
- M16: Execution-window deferrals (the M15 in-memory behavior) are now persisted when the observability store is configured, so deferred PR/MR events survive restarts and never resume earlier than the next allowed instant; the comment-command deferral notice is posted once per deferral.
- Repo:
packages/llm/assets/models-dev.jsonis now tracked via Git LFS (.gitattributes+ history rewrite); fresh clones requiregit lfsinstalled. - M5:
Plan.mdcurrent execution package updated to reflect actual delivery status (runtime bundle, MCP config injection, agent repair, MCP state file reading marked delivered). - Plan:
Plan.mdmilestone table updated: M5→基本完成, M6→部分完成 (GitHub e2e 验收, GitLab/SVN→Backlog), M8→大部分完成 (OTel 接入, eval CLI 添加), M9→进行中. Low-priority items moved to explicit Backlog section. - Docs:
Note.mdmoved todevelopment/README.md; all references updated across skills and docs. - Skill:
.agents/skills/remote-deployment/SKILL.mdstripped of hardcoded deployment targets (IP, ports, directories, domains); values replaced with placeholders. Concrete environment info lives indevelopment/README.md.
- GitHub/Gitea managed issues resolve head-commit authors before the retained push pusher, including automatic Git batches with only name/email metadata. Fixed Gitea's
/git/commits/{sha}lookup and empty webhook usernames, preserved email blacklists, and cached concurrent lookups. Creation retries without assignees only for explicit 422 assignment validation errors. GitLab issue creation/assignment remains unimplemented (gitlab_mr_reviewpublishes discussions/notes). - Dashboard lands on the Overview tab again instead of the Live worker view; Live is now the second tab and only polls while selected.
- GitLab
Push Hook/git_pushnow use automatic commit branch filtering and receipt persistence; all-zero branch creation/deletion ranges are ignored consistently across Git providers. PR webhooks reject malformedbase.refvalues instead of treating them as unknown targets. Configuration example checks now include standalone PR policies. - M15:
review.auto_commit.schedulenow also gates asynchronous PR/MR, issue, and comment processing. Previously only automatic-commit batches were window-gated, so PR events ran immediately at any hour (observed in production: apull_requestrun executed 13:54–14:31 inside a configured 13:40–18:00 gap). Outside the windows the first attempt and every retry now defer to the next allowed instant, logged astrigger processing deferred by execution window; deferral is in-memory like the rest of the async trigger path. - M8: Prometheus review duration histogram now keeps cumulative bucket/sum/count values while bounding only the raw duration sample buffer.
- M15: Auto-commit metadata expansion for git receipts failed terminally in production (
EACCES: permission denied, rmdir '/app'). The scheduler's metadata adapter cloned into the process working directory (read-only/appinside the runtime image) instead of the per-workspace source root, fetched only once per cached adapter, and never resolved GitHub App installation tokens. The adapter now clones underworkspaces/<workspaceId>/source/<repo>, re-fetches every sync (alwaysFetch), and re-resolves tokens per sync (tokenProvider). The scheduler adapter cache is additionally keyed by workspaceId so two workspaces watching the same repo never share a clone directory. Affected production receipts can be recovered by clearingmetadata_terminal_error/metadata_attemptsso the scheduler re-expands them. - M8: Inline webhook review processing now records metrics and persists run snapshots consistently with async processing.
- M9: Podman
invalid internal statusroot cause identified and fixed on production server (podman --storage-driver=overlay system migrate). - M8:
EvalUnexpectedProblemmissingcategoryfield in eval package interface. - M8: Eval
runEvalmissing/unexpected problem matching now symmetrically checksfile + line + severity + category + messagePattern. - M8: Eval
messagePatterninterface field now actually used in matching logic (RegExp and string support).
- Initial AICR monorepo with workspace packages:
@aicr/core,@aicr/cli,@aicr/server,@aicr/llm,@aicr/vcs,@aicr/outputs,@aicr/sandbox,@aicr/agents,@aicr/store,@aicr/mcp-output,@aicr/eval. - Review orchestration pipeline: VCS adapter → prompt preparation → LLM gateway → output collector → publisher dispatch.
- Multi-provider LLM gateway with bounded retry, fallback chain, and budget controls.
- VCS adapters: Git, Perforce (P4), Gitea webhook.
- Output channels: Gitea PR review, GitHub PR review, GitLab MR review, Gitea/GitHub problem issues, Feishu/WeCom IM bots.
- Agent runtime bundle with Kilo Code adapter and native MCP tool manifest.
- Sandbox backends: native, docker, podman.
- Config schema with Zod validation, workspace instances, and channel routing.
- Review deduplication and async queue support (in-memory, Redis).
- Structured logging with pino and secret scrubber.