feat: update AI automation agents, add reviewer agent, enhance CI #26
Reference in New Issue
Block a user
Delete Branch "feat/ai-automation-updates"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Changes
Agents Updated
New Agent
CI Enhanced
Review: Request changes ⛔
Reviewed the actual PR diff (against
origin/main):.gitea/workflows/ci.yaml+ the four.opencode/agents/*.mdfiles. Verified by reading the code, a clean build, unit tests, and an ASan+UBSan build & run.(Note: my first pass accidentally diffed against a stale local
mainand pulled in the already-merged delta-transfer code from #22. Findings below are scoped to this PR; delta-code findings are noted separately at the end.)🔴 Critical
1. The sanitizer job never fails — and it is currently masking real bugs in the tree
.gitea/workflows/ci.yaml— both test steps in thesanitizerjob end with|| true:ASan/UBSan exit non-zero on any finding, so
|| trueturns this job into a permanent green check. Commit4a5bf67justifies this with "pre-existing leaks expected" — but this isn't hypothetical. I built this branch with the job's exact flags (-fsanitize=address,undefined -fno-omit-frame-pointer -g) and ran./build/tests:test_delta_serialize_roundtripleaks literal buffers allocated atsrc/shared/delta.c:388. Root cause:delta_deserialize()never sets.typein theDELTA_OP_LITERALbranch (compare the match branch atdelta.c:365), sodelta_destroy()can't tell literals from matches and never frees them. That's an uninitialized-field bug, not just a leak.test_scannerleaks (~4.3 KB in 10 allocations).So the job as written hides both pre-existing issues and a real uninitialized-memory bug. Please either:
|| trueand fix the reported leaks, orLSAN_OPTIONS=suppressions=...) so anything new fails the build.🟡 Warnings
2. clang-tidy job only fails on
error:— analyzer findings arewarning:The enabled check groups (
bugprone-*,clang-analyzer-*,misc-*) emitwarning:, noterror:, sogrep -q " error:"will essentially never trigger on their findings — the job only fails on hard compile errors. If gating on analyzer findings is intended, grep forwarning:too (possibly with a baseline). If warnings-as-informational is the intent, a comment saying so would help.(
compile_commands.jsonis fine —CMAKE_EXPORT_COMPILE_COMMANDS ONis set inCMakeLists.txt:5.)3.
apt-get install -y clang-tidy || true+ silent skipCombined with #2, the whole clang-tidy job can no-op without failing. The
echo "clang-tidy not available, skipping"is good; consider also::warningannotations or a step summary so a skipped job is visible in the UI.🔵 Suggestions
ci: trigger workflow runcommit (2ffd324).test_scannerleaks so the sanitizer job can run unmasked.✅ What looks good
CMakeLists.txt:1) and documents the OpenSSL/xxHash/FetchContent deps; integrator and test-writer correctly referencetests/integration/+ pytest instead of the removedtest.py; no stale paths found.reviewer.mdagent is well-formed (valid frontmatter, sensible review dimensions).⚠️ Out of scope for this PR, but verified while testing the sanitizer job
The ASan build + live wire tests surfaced serious issues in the already-merged delta-transfer code from #22 (present on
main). Filing these here so they don't get lost — recommend a follow-up issue/PR:delta_apply()(src/shared/delta.c:415–438): noout_pos + len <= new_file_sizecheck before thememcpys; the final size check fires after the corruption. Reproduced end-to-end with a malicious-client PoC against an ASan server (WRITE of size 16 ... delta_apply ← receive_delta_file ← receive_incremental_check). Unauthenticated in TCP mode.src/shared/file.c:171–277,314–332): onceSTATUS_DELTA_SIGNATUREis sent, any failure makes the server sendSTATUS_NEXTa second time and hang waiting for a full file the client never sends. Reproduced live.delta_compute()returns NULL (src/client/client_send.c:59–61): returns without sendingSTATUS_NEXTwhile the server blocks inreceive_status.delta_deserialize()error paths leak prior literal allocations (4 paths missing cleanup); noinstruction_countsanity check (~137 GB transient malloc from a 12-byte payload);delta_computeblock scan is O(file_size × block_count) — impractical at the 256 MB ceiling.Happy to open a dedicated issue with full repro details if you want.
Verdict: The agent changes are merge-ready, but the PR's headline feature — the sanitizer job — is neutralized by
|| trueand is actively hiding a real uninitialized-memory bug. Please fix finding #1 before merge; #2/#3 at your discretion.4a5bf67b59to20a26e2f5a20a26e2f5ato64b8a1a95064b8a1a950to326aa5d08bRe-review: Request changes ⛔
The force-push addressed the previous
|| trueissue (now usesLSAN_OPTIONS=suppressions=.lsan-suppressions.txtinstead). Verified locally: ASan+UBSan build clean, unit tests pass, 39/49 integration tests pass with LSAN suppression.🔴 Critical
1. cmake-expert.md introduces misleading commented-out sanitizer lines (
.opencode/agents/cmake-expert.md:24-25,88)The diff adds these new lines to the CMake snippet:
And line 88 still says "Sanitizer support is commented out but present". This is false —
origin/main'sCMakeLists.txthas a live-DSANITIZER=address|thread|noneoption block, not commented-out lines. This PR introduces wrong code to match a wrong claim. Any agent reading this doc would produce non-standard builds.Fix: Replace the commented-out lines with the actual SANITIZER option block from CMakeLists, and update the text to reference
-DSANITIZER=address.2. "When Adding Sanitizer Support" uses
ENABLE_ASAN/ENABLE_TSANpattern (.opencode/agents/cmake-expert.md:172-198)The section shows three separate
option(ENABLE_ASAN ...)/option(ENABLE_TSAN ...)/option(ENABLE_UBSAN ...)flags. The project uses a single-DSANITIZER=address|thread|nonecache variable. An agent following this doc would add non-matching boilerplate. Fix: Update to recommend the existingset(SANITIZER ...)pattern, or remove the section.3. integrator.md YAML example uses stale
v6tag and raw flags (.opencode/agents/integrator.md:113-128)container: gitea.tap-tap.win/taptap/fastsync-ci:v6— actual CI uses:v7-DCMAKE_C_FLAGS="-fsanitize=address,undefined ..."— origin/main supports-DSANITIZER=addressAgents copying this example for new CI jobs would produce broken YAML.
🟡 Warnings
4. clang-tidy job never gates (
.gitea/workflows/ci.yaml:75-79) —grepthen just echoes a message; the step passes regardless of findings. Compare with lint job's--Werror/--error-exitcode=1. If intentionally informational, add a comment. Otherwise, gate on errors.5. "Fix leaks" claim is overstated — the only "fix" is
.lsan-suppressions.txtsuppressingconfig_create. The actual leak (246 bytes in 4 allocations, confirmed by ASan) is still present. Rename the commit or addconfig_destroy()beforereturninclient_cli.c.6. integrator.md example YAML omits the symlink + integration test steps — any agent adding a sanitizer-like job from this doc would produce broken YAML.
🔵 Suggestions
conftest.pyis attests/conftest.py(nottests/integration/conftest.py) for discoverability.chunk.c:98,135— outside PR scope, but tech debt.✅ What's Fixed
|| trueis gone — integration tests now run properly withLSAN_OPTIONS=suppressions=...config_createleak (verified: 39/49 integration tests pass with it, 25 fail without)cmake_minimum_required4.1→3.22, xxHash/OpenSSL/ZSTD checks addedtest.py→tests/integration/in integrator.md and test-writer.md ✅./build/)Verdict: Request changes. The
|| trueremoval and LSAN suppression are real progress, but the cmake-expert.md actively introduces new inaccuracies (commented-out sanitizer lines that don't match reality), the integrator.md example uses stale:v6and wrong flags, and the clang-tidy job runs without gating. Fix the three critical doc issues before merge.9b2d697256to5c686b0655Re-review 2: Approve ✅
All 3 critical + 3 warning items from the last review are fixed. The config leak is now actually fixed (not just suppressed), docs corrected, and the LSAN suppression file emptied.
Verified fixes
ENABLE_ASAN/ENABLE_TSANpatternset(SANITIZER ...)v6tag + raw flagsv7,-DSANITIZER=, symlink + integration test steps documented::warning::annotation, adds "no issues found" for clean caseclient_cli.c(goto cleanup +config_delete); LSAN suppressions emptiedConfig leak fix
src/client/client_cli.cnow properly freesconfigviagoto cleanup+config_delete(config)on all early-exit paths. Theconfig_owned_by_pipelineflag prevents double-free whensend_files/send_files_multithreadedtakes ownership. Clean, idiomatic pattern. LSAN suppressions file emptied to just a format comment — the actual leak is gone.cmake-expert.md quality
The doc now accurately describes the project's sanitizer approach:
address/thread/noneelseifblock" — clear and actionableintegrator.md quality
The YAML example now matches real CI structure:
v7tag,-DSANITIZER=configure, symlink step, unit + integration tests with LSAN suppression. Includes explanation of why the symlink is needed. Agents following this for new CI jobs will produce correct YAML.Verdict: Approve. All previous critical and warning items addressed with clean, targeted changes. No new issues found. The config leak fix is a genuine improvement to
client_cli.c(not just a suppression), and the agent docs now accurately reflect the project's current CMake and CI patterns.