Skip to content

ci(reborn): run the full reborn_cli dependency closure on every PR - #5110

Merged
serrrfirat merged 2 commits into
mainfrom
firat/reborn-closure-on-pr
Jun 21, 2026
Merged

serrrfirat merged 2 commits into
mainfrom
firat/reborn-closure-on-pr

Conversation

@serrrfirat

Copy link
Copy Markdown
Collaborator

What

Make PR CI's reborn-tests matrix run the full ironclaw_reborn_cli dependency closure (64 crates) instead of the 21-crate name-prefix allowlist.

Why

Only 10 of the 21 allowlisted crates overlap the actual closure. 43 closure crates the shipped Reborn binary links — auth, host_runtime, skills, first_party_extensions, extensions, dispatcher, llm, safety, memory, network, turns, host_api, loop_support, threads, … — ran their own test suites only via the nightly/manual closure path, never on a PR (only exercised indirectly by the 4 root integration partitions).

That's exactly the gap that let the bugs in #5105 / #5108 (github surface, skills TOCTOU, gsuite wrong-account egress, loop_support/threads/auth) through normal PR CI — they only surfaced when the closure was run by hand.

How

  • package-matrix: union of the existing allowlist and cargo tree -p ironclaw_reborn_cli -e normal,build ∩ workspace members = 64 crates. Union (not replace) so channel adapters / webui_v2 are never dropped.
  • package-feature-flags.sh: fallback features (default/libsql when declared) for closure crates without an explicit recipe; previously-allowlisted no-flag crates kept flag-free (behavior unchanged).

Verification

The 3 closure reds this catches are already fixed on main (#5105, #5108), so the closure should be green. This PR's own CI run is the 64/64 verification — hence draft.

Tradeoff / follow-ups

21 → 64 parallel crate jobs raises compute and, if runner concurrency is capped, may raise wall-clock as jobs queue.

  1. build-once nextest archive + shard to cut redundant compiles (spike ci(spike): experimental full-suite gate - nextest archive + mold + sccache + sharding #5086)
  2. bake a few runs → promote reborn-tests to a required check
  3. cut v1 (test.yml / Tests (all-features), ~29m) → gate drops to ~10–12m

Automated agent-authored.

@coderabbitai

coderabbitai Bot commented Jun 21, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • Chores
    • Enhanced test coverage matrix to include full dependency closure alongside existing allowlist, ensuring comprehensive test coverage.
    • Improved automatic feature flag detection for build dependencies with intelligent fallback mechanism that inspects declared features and enables relevant defaults.

Walkthrough

The reborn-tests CI workflow is updated to build closure_packages from cargo tree over ironclaw_reborn_cli plus workspace crates and union it with the existing allowlist_packages set. package-feature-flags.sh gains a fallback_feature_flags() function that auto-detects default/libsql features via cargo metadata, a new explicit ironclaw_host_runtime mapping, and a grouped no-op block for several ironclaw_* crates.

Changes

Reborn CI: closure-based package matrix and fallback feature flags

Layer / File(s) Summary
fallback_feature_flags and case statement
scripts/ci/package-feature-flags.sh
Adds fallback_feature_flags() that introspects cargo metadata to conditionally emit --features default,libsql; adds explicit ironclaw_host_runtime clause (test-support,libsql); groups several ironclaw_* packages as no-op; routes all unrecognized packages through fallback_feature_flags instead of the old implicit empty output.
Package matrix closure union
.github/workflows/reborn-tests.yml
Renames allowlist output to allowlist_packages, computes closure_packages from cargo tree (normal+build deps of ironclaw_reborn_cli) and workspace crates via cargo metadata, fails if closure is empty, then unions both sets via jq deduplication to form the final packages matrix output.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related issues

Possibly related PRs

  • nearai/ironclaw#5112: Targets ironclaw_host_runtime with test fixes/ignores, which this PR explicitly adds to the feature flags case statement with test-support,libsql.

Poem

cargo tree roots dig deep and wide,
allowlist and closure run side by side,
jq dedupes the tangled mesh,
fallback_feature_flags keeps tests fresh—
no crate left dark in the CI night. 🦀

🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning Description covers What/Why/How with verification plan, but omits required Change Type, Validation checklist, and Review track sections from template. Add Change Type checkbox selection (CI/Infrastructure applies), complete Validation checklist items, and specify Review track (likely C for CI changes).
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed Title follows Conventional Commits (ci(reborn): ...) and accurately describes the main change: expanding reborn-tests matrix to the full dependency closure.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-5110 June 21, 2026 13:06 Destroyed
@github-actions github-actions Bot added scope: ci CI/CD workflows size: M 50-199 changed lines risk: medium Business logic, config, or moderate-risk modules contributor: core 20+ merged PRs labels Jun 21, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the CI packaging script scripts/ci/package-feature-flags.sh to introduce a fallback mechanism that automatically detects and enables default and libsql features for Rust crates without explicit recipes. It also maintains a list of specific crates that should remain flag-free. The review feedback suggests simplifying the fallback_feature_flags function by offloading the filtering and formatting logic entirely to jq, which eliminates the need for multiple subshells and complex Bash array manipulation.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +18 to +39
local feature_list
feature_list="$(
jq -r --arg package "${package}" '
.packages[]
| select(.name == $package)
| .features
| keys[]
' <<< "${metadata}"
)"

local features=()
if printf '%s\n' "${feature_list}" | grep -Fxq "default"; then
features+=("default")
fi
if printf '%s\n' "${feature_list}" | grep -Fxq "libsql"; then
features+=("libsql")
fi

if [ "${#features[@]}" -gt 0 ]; then
local IFS=,
printf '%s\n' "--features ${features[*]}"
fi

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

We can simplify this function significantly by performing the entire feature filtering and formatting logic directly inside jq. This avoids creating multiple subshells (printf and grep twice) and simplifies the Bash array/IFS manipulation, making the script cleaner, faster, and more maintainable.

Suggested change
local feature_list
feature_list="$(
jq -r --arg package "${package}" '
.packages[]
| select(.name == $package)
| .features
| keys[]
' <<< "${metadata}"
)"
local features=()
if printf '%s\n' "${feature_list}" | grep -Fxq "default"; then
features+=("default")
fi
if printf '%s\n' "${feature_list}" | grep -Fxq "libsql"; then
features+=("libsql")
fi
if [ "${#features[@]}" -gt 0 ]; then
local IFS=,
printf '%s\n' "--features ${features[*]}"
fi
jq -r --arg package "${package}" '
.packages[]
| select(.name == $package)
| .features
| keys
| map(select(. == "default" or . == "libsql"))
| if length > 0 then "--features " + join(",") else empty end
' <<< "${metadata}"

@railway-app

railway-app Bot commented Jun 21, 2026 •

Copy link
Copy Markdown

🚅 Deployed to the ironclaw-pr-5110 environment in ironclaw-ci-preview

Service Status Web Updated (UTC)
ironclaw ✅ Success (View Logs) Web Jun 21, 2026 at 6:51 pm

serrrfirat and others added 2 commits June 21, 2026 21:46
PR CI's reborn-tests matrix was a name-prefix allowlist of 21 reborn/
product-family crates. But only 10 of those overlap the actual
`ironclaw_reborn_cli` dependency closure (53 workspace crates) — so 43
crates the shipped Reborn binary links (auth, host_runtime, skills,
first_party_extensions, extensions, dispatcher, llm, safety, memory,
network, turns, host_api, loop_support, threads, ...) ran their own test
suites ONLY via the nightly/manual closure path, never on a PR. They
were exercised on PR only indirectly by the 4 root integration
partitions, which don't run those crates' own unit/contract tests.

That gap is exactly why the bugs fixed in #5105/#5108 (host_runtime
github surface, skills TOCTOU, gsuite wrong-account egress, loop_support/
threads/auth) slipped through normal PR CI and only surfaced when the
closure was run by hand.

This makes the closure the default PR matrix — "run everything on every
PR":

- package-matrix: discover the union of the existing allowlist and the
  `cargo tree -p ironclaw_reborn_cli -e normal,build` closure ∩ workspace
  members (64 crates). Union (not replace) so non-closure reborn-family
  crates — channel adapters, webui_v2 — are never dropped from coverage.
- package-feature-flags.sh: derive fallback features (default/libsql when
  declared) for closure crates without an explicit recipe; keep the
  previously-allowlisted no-flag crates flag-free so their behavior is
  unchanged.

The 3 closure reds this would have caught are already fixed on main
(#5105, #5108), so the closure should be green — this PR's own CI run is
the 64/64 verification.

Tradeoff: 21 -> 64 parallel crate jobs raises compute and, if runner
concurrency is capped, may raise wall-clock as jobs queue. Follow-ups:
(1) build-once `nextest archive` + shard to cut redundant compiles
(spike #5086); (2) bake a few runs, then promote reborn-tests to a
required check; (3) cut v1 (`test.yml` / Tests (all-features), ~29m) so
the gate drops to ~10-12m.

Automated agent-authored.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…he closure

host_runtime's integration tests (tests/) link the lib as a normal
dependency, so cfg(test) is false there and the deterministic test-mode
behavior they assert is gated behind `feature = "test-support"`. The
generic default/libsql fallback runs the lib in production mode, so give
host_runtime an explicit `--features test-support,libsql` recipe — libsql
exercises the embedded-DB paths without needing a Postgres server (which
the crate-tests job does not provision).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@serrrfirat
serrrfirat force-pushed the firat/reborn-closure-on-pr branch from bbf71e9 to 857355d Compare June 21, 2026 18:46
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-5110 June 21, 2026 18:46 Destroyed
@serrrfirat
serrrfirat marked this pull request as ready for review June 21, 2026 19:04

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/reborn-tests.yml:
- Around line 142-145: The error message in the condition checking
closure_packages is misleading because it doesn't distinguish between cargo tree
failing versus returning an empty result. Modify the script to separately
capture and check the exit status of the cargo tree command that generates
closure_packages. If cargo tree exits with a non-zero status, output an error
message indicating the tool failure. Only check for empty or "[]" results if
cargo tree succeeded, and keep the current message for that case.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: ff1bde2e-3b48-4994-bf7f-32b98b592496

📥 Commits

Reviewing files that changed from the base of the PR and between 9ccb236 and 857355d.

📒 Files selected for processing (2)
  • .github/workflows/reborn-tests.yml
  • scripts/ci/package-feature-flags.sh

Comment on lines +142 to +145
if [ -z "${closure_packages}" ] || [ "${closure_packages}" = "[]" ]; then
echo "No Reborn CLI workspace dependency closure crates discovered" >&2
exit 1
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial | 💤 Low value

Misleading error message on cargo tree failure.

If cargo tree fails, the script will hit this error message, but "No Reborn CLI workspace dependency closure crates discovered" suggests a dependency-graph issue rather than a tool failure. Consider checking cargo tree exit status separately or clarifying the message.

Clearer error handling
+          if ! cargo tree -p ironclaw_reborn_cli -e normal,build --prefix none >/dev/null 2>&1; then
+            echo "cargo tree failed for ironclaw_reborn_cli" >&2
+            exit 1
+          fi
+
           closure_packages="$(
             comm -12 \
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/reborn-tests.yml around lines 142 - 145, The error message
in the condition checking closure_packages is misleading because it doesn't
distinguish between cargo tree failing versus returning an empty result. Modify
the script to separately capture and check the exit status of the cargo tree
command that generates closure_packages. If cargo tree exits with a non-zero
status, output an error message indicating the tool failure. Only check for
empty or "[]" results if cargo tree succeeded, and keep the current message for
that case.

This branch was successfully deployed

No deployments
ironclaw-ci-preview / ironclaw-pr-5110 — 857355d5 Deployed Jun 21, 2026 by railway-app[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contributor: core 20+ merged PRs risk: medium Business logic, config, or moderate-risk modules scope: ci CI/CD workflows size: M 50-199 changed lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant