Skip to content

fix(kiloclaw) smoke prod parity - #4901

Merged
St0rmz1 merged 3 commits into
mainfrom
fix/kiloclaw-smoke-prod-parity
Jul 30, 2026
Merged

fix(kiloclaw) smoke prod parity#4901
St0rmz1 merged 3 commits into
mainfrom
fix/kiloclaw-smoke-prod-parity

Conversation

@St0rmz1

@St0rmz1 St0rmz1 commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Summary

The live smoke asserted the candidate image in one shape only, an instance that
upgraded onto a persisted root. Nothing covered a brand new instance, which is
what a customer provisioned after a release actually gets. It also ran on a free
model route and booted a container configuration that production never uses,
which produced failures that looked like image regressions but were not.

This adds the missing shape, moves the run onto a paid route, and closes two
gaps between the local Docker harness and how instances actually run on Fly.

New install coverage. The upgrade run now asserts the candidate twice: once
on the baseline's persisted root (an upgrading instance) and once on a brand new
root (a new signup). Both legs run the same 29 assertions, so neither is a token
pass.

Each leg proves its own shape. assert_root_shape checks the root is empty
or seeded as expected before the container boots. Without it, a silent failure of
the fresh root swap would turn the new instance leg into a second upgrade run
that still reported green while covering nothing new.

The baseline leg no longer runs a live turn. It exists to generate the
persisted root. A turn there asserts the version being replaced, proves nothing
about the candidate, and was the source of repeated failures that were mistaken
for candidate regressions.

Paid route by default. kilocode/kilo-auto/balanced, matching what
production instances use. Free routes are rejected, with ALLOW_FREE_SMOKE_MODEL=true
as a deliberate override. This was confirmed against a live instance: openclaw
2026.6.11 on kilocode/kilo-auto/free fails every turn with "provider rejected
the request schema or tool payload", while the same image on a paid route reaches
the provider normally. A free route run therefore tests provider free tier
behavior rather than the image under test.

Production parity in the container. Containers now boot with
AUTO_APPROVE_DEVICES=true, which every real instance sets unconditionally in
services/kiloclaw/src/gateway/env.ts as a reserved system var. Without it the
smoke booted a configuration that does not exist in production: the controller's
gateway client device auto approval was disabled and openclaw.json never got
gateway.controlUi.allowInsecureAuth.

Warm up handling. A settle before the live turn, with a short opportunistic
poll for an already approved device. On Fly a device is granted operator.write
within seconds. In local Docker a turn landing too early dies with
1008 pairing required, which reads as a product failure but is warm up.

Billing is named as billing. A 402 is tagged NO_CREDITS and reported as a
billing state with the fix, rather than leaving a credits problem looking like a
regression.

Verification

Run locally against prebuilt images. Nothing here runs in CI.

  • Upgrade mode, paid route, org credits: 72 passed, 0 failed. All three
    legs green, including both live turns and all three root shape assertions.
  • Fresh mode after the timing change: 28 passed, 0 failed.
  • Full validator gate against the 2026.7.1 bump using this harness:
    Phase 1 keyless 17 passed, 0 failed, Phase 2 smoke 72 passed, 0 failed.
  • Free route guard: supplying KILOCODE_SMOKE_MODEL=kilocode/kilo-auto/free
    refuses before any image is built.
  • Shape assertions observed distinguishing the legs: baseline and fresh legs
    report empty, the upgraded leg reports seeded.

Visual Changes

N/A

Reviewer Notes

The device scope poll in wait_for_device_scopes usually cannot succeed, and the
comment says so. Verified against a live instance: /root/.openclaw/devices does
not exist before the first client connects, and paired.json is created by that
connection, so there is normally no signal to wait for and the settle is what does
the work. The poll is kept short for the case where a previous leg on the same
persisted root already left an approved device. It is never fatal, because absence
is the normal state.

Run time goes up. There is one more container boot and live turn, plus the settle
before each turn. DEVICE_SCOPE_POLL_SECS and DEVICE_SCOPE_SETTLE_SECS are
overridable if that becomes annoying.

Rejecting free routes is a behavior change for anyone who currently runs the smoke
with a free key. The error names the override.

openclaw-upgrade-image-checks.sh here carries documentation edits only. The
actionRequiresTarget check fix lives on the 2026.7.1 bump branch and is
deliberately not duplicated here.

St0rmz1 added 2 commits July 30, 2026 10:49
…on a paid route

  The live smoke asserted the candidate in one shape only, an instance upgraded
  onto a persisted root. Nothing covered a brand new instance, which is what a
  customer provisioned after a release actually gets. Add a third leg that runs the
  same 29 assertions against the candidate on a fresh root, and assert each leg's
  root shape before boot so a leg that is not in its claimed shape fails loudly
  instead of silently duplicating another leg.

  Demote the baseline leg to seeding that root, with no live turn. It asserts the
  version being replaced, proves nothing about the candidate, and was the source of
  repeated failures that were mistaken for candidate regressions.

  Run on a paid route by default (kilocode/kilo-auto/balanced, what production
  instances use) and reject free routes. Verified against a live instance: openclaw
  2026.6.11 on kilocode/kilo-auto/free fails every turn with 'provider rejected the
  request schema or tool payload' while the same image on a paid route reaches the
  provider normally, so a free-route run tests provider free-tier behaviour rather
  than the image. Tag a 402 as NO_CREDITS and report it as a billing state.

  Boot containers with AUTO_APPROVE_DEVICES=true, which every production instance
  sets unconditionally, and settle before the live turn to clear the device warm-up
  window that local Docker exposes and Fly does not.
Comment thread services/kiloclaw/scripts/tests/smoke-live-provider.sh Outdated
Comment thread services/kiloclaw/scripts/tests/smoke-live-provider.sh
@kilo-code-bot

kilo-code-bot Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

The incremental commit resolves both previously reported findings — the mid-run rm -rf on the container-owned root is gone in favor of a tracked second root removed non-fatally at EXIT, and assert_root_shape now fails loudly on an unrecognized shape — with no new issues in the changed lines.

Resolved since last review
  • services/kiloclaw/scripts/tests/smoke-live-provider.sh:818 — the fresh-root leg now allocates a second mktemp -d root instead of deleting the baseline-seeded, root-owned tree mid-run; ROOTDIRS collects every root and cleanup removes each with rm -rf ... 2>/dev/null || true, so an EACCES tree can no longer abort the gate before the results summary.
  • services/kiloclaw/scripts/tests/smoke-live-provider.sh:708assert_root_shape's case gained a *) branch that records a failing check, so a typo'd or future shape label can no longer pass a leg while asserting nothing.
Notes
  • ROOTDIRS is always non-empty before trap cleanup EXIT is installed, so the "${ROOTDIRS[@]}" expansion is safe under set -u.
  • DEVELOPMENT.md:594 now documents the paid default route and the two-leg upgrade behavior, closing the stale-docs note from the previous review.
  • Trade-off, not a defect: both roots persist until process exit, so peak disk use for an --upgrade run is roughly doubled.
Files Reviewed (2 files)
  • services/kiloclaw/scripts/tests/smoke-live-provider.sh
  • services/kiloclaw/DEVELOPMENT.md
Previous Review Summary (commit 3e4b4dc)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 3e4b4dc)

Status: 2 Issues Found | Recommendation: Address before merge

Executive Summary

The new fresh-root leg deletes a container-root-owned bind mount with a bare rm -rf under set -e, which can abort the entire gate after the earlier legs already passed; the rest of the change (paid-route default, root-shape assertions, AUTO_APPROVE_DEVICES parity) is sound.

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 1
Issue Details (click to expand)

WARNING

File Line Issue
services/kiloclaw/scripts/tests/smoke-live-provider.sh 797 rm -rf "$ROOTDIR" on a root-owned bind mount can fail with EACCES; under set -euo pipefail the run aborts before the fresh-root leg and before the results summary

SUGGESTION

File Line Issue
services/kiloclaw/scripts/tests/smoke-live-provider.sh 699 assert_root_shape's case has no *) branch, so an unrecognized shape argument silently asserts nothing — the same silent-no-coverage failure the function exists to prevent
Notes
  • services/kiloclaw/DEVELOPMENT.md:594 still documents the live smoke as running on kilocode/kilo-auto/free, which this PR now rejects by default. Not flagged inline because that file is outside the diff.
  • Verified the AUTO_APPROVE_DEVICES=true production-parity claim against services/kiloclaw/src/gateway/env.ts:280 (set unconditionally) — accurate.
  • The [ "$root_shape" != "any" ] && assert_root_shape ... guard at line 715 was checked against set -e semantics; a false test there is exempt from errexit, so it is safe.
Files Reviewed (4 files)
  • services/kiloclaw/scripts/tests/smoke-live-provider.sh - 2 issues
  • services/kiloclaw/scripts/tests/openclaw-upgrade-validate.sh - 0 issues
  • services/kiloclaw/scripts/tests/openclaw-upgrade-image-checks.sh - 0 issues
  • services/kiloclaw/scripts/tests/README.md - 0 issues

Fix these issues in Kilo Cloud


Reviewed by claude-opus-5 · Input: 26 · Output: 4.6K · Cached: 604K

Review guidance: REVIEW.md from base branch main

  The fresh-root leg deleted the baseline's bind mount with a bare rm -rf under
  set -euo pipefail. The container writes /root as uid 0, so on native Linux Docker
  that tree is root-owned on the host and the delete fails with EACCES for a
  non-root user, aborting the run after two legs had passed and before the results
  summary. Allocate a second root instead and remove every allocated root at EXIT,
  where failures cannot abort the run.

  Add a default branch to assert_root_shape so an unrecognized shape argument fails
  loudly instead of falling through and asserting nothing, which was the silent
  no-coverage the function exists to prevent.

  Update DEVELOPMENT.md, which still documented the live smoke as running on
  kilocode/kilo-auto/free.
@St0rmz1
St0rmz1 merged commit 01a4ccf into main Jul 30, 2026
17 checks passed
@St0rmz1
St0rmz1 deleted the fix/kiloclaw-smoke-prod-parity branch July 30, 2026 20:14
St0rmz1 added a commit that referenced this pull request Jul 30, 2026
  Brings in the reworked live smoke (#4901): paid-route default, new-install and
  upgraded shapes, root-shape assertions, and the AUTO_APPROVE_DEVICES production
  parity fix. Lockfile conflict resolved by regenerating against the merged
  package.json files rather than hand-merging.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants