Skip to content

chore: remove .kilo_workflow from monorepo (machine-local) - #4909

Merged
iscekic merged 19 commits into
mainfrom
workflow-hardening-ceec
Jul 31, 2026
Merged

iscekic merged 19 commits into
mainfrom
workflow-hardening-ceec

Conversation

@iscekic

@iscekic iscekic commented Jul 31, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

What: Remove .kilo_workflow and the seven workflow role agents from the monorepo. Product E2E helpers that landed on this branch (record.sh, Appium multi-flow, runbook cleanup) stay.

Why: The multi-agent delivery workflow is personal/machine-local automation. Shipping it in the shared cloud repo pollutes colleague agent pools (role defs under .kilo/agent/, learnings, scripts agents discover and follow). Moving it out keeps the monorepo product-only.

How:

  • Delete .kilo_workflow/ entirely (scripts, WORKFLOW.md, committed learnings)
  • Delete workflow role agents: starter, planner, orchestrator, plan-reviewer, implementer, impl-reviewer, e2e-verifier
  • Delete dev/local/workflow-scripts.test.ts (only tested the removed scripts)
  • Drop the worktree-prepare copy of workflow system learnings
  • Rewrite apps/mobile/e2e/AGENTS.md (and related comments) to call pnpm dev:* / simulator helpers directly — zero remaining .kilo_workflow string references in the tree
  • Keep product-side E2E improvements from this branch: apps/mobile/e2e/record.sh, Appium multi-flow, record.sh tests

Machine-local home: ~/Projects/.kilo_workflow (local git repo; role agents at .kilo/agent/; system learnings untracked under learnings/system/). Snapshot matches the pre-removal tip of this branch.

Verification

  • rg '\.kilo_workflow' over the worktree → no matches
  • pnpm exec tsx --test dev/local/appium-wrapper.test.ts — 11/11 pass
  • No E2E device runs (tooling/docs only)

Visual Changes

N/A

iscekic added 7 commits July 31, 2026 04:09
Shorten slot acquire to 8 minutes with a one-shot holders line, enumerate
booted/unclaimed and claimed-but-dead devices in status, and fold prebuild
plus claim/build into ios/android starts with a compact JSON stdout contract
and bundle --ios-only.
Document the take→start→shards→serialized→stop→free lifecycle, platform
scope table with iOS-only default, folded claim/build starts, and status
device findings in WORKFLOW.md, the runbook, and README.
Add record.sh for segment-scoped device video, teach multi-flow Appium
batching, inject section-level E2E_ARTIFACTS for verifier reuse, and
document the contracts in the runbook and e2e-verifier role.
Add await-interactive --until-launched and 10-minute cadence, normalize
reviewer FINDINGS: 0 to No findings., add steer --interrupt for in-flight
turn cancel, shorten Kilobot wait to 600s, and document the starter
monitor-to-dispatch lifecycle.
…rning

Point agents at pnpm dev:setup-env and dev:seed for env/account blockers,
note iOS-only E2E default in the README, and rewrite the android-emulator-
died learning around the new status DEAD device line.
Name record.sh stop on VERIFICATION BLOCKED recovery and the shared
E2E slot lifecycle so orchestrators cannot orphan simctl/screenrecord.
@iscekic iscekic self-assigned this Jul 31, 2026
Comment thread dev/local/appium-wrapper.test.ts
Comment thread dev/local/workflow-scripts.test.ts Fixed
Comment thread dev/local/workflow-scripts.test.ts Fixed
Comment thread dev/local/workflow-scripts.test.ts Fixed
Comment thread dev/local/workflow-scripts.test.ts Fixed
Comment thread dev/local/workflow-scripts.test.ts Fixed
Comment thread dev/local/workflow-scripts.test.ts Fixed
Comment thread dev/local/workflow-scripts.test.ts Fixed
Comment thread dev/local/workflow-scripts.test.ts Fixed
Comment thread dev/local/workflow-scripts.test.ts Fixed
Comment thread apps/mobile/e2e/record.sh
Comment thread apps/mobile/e2e/record.sh Outdated
Comment thread apps/mobile/e2e/record.sh Outdated
Comment thread apps/mobile/e2e/record.sh
Comment thread .kilo_workflow/e2e-slot-status.sh Outdated
Comment thread .kilo_workflow/e2e-start-resource.sh Outdated
Comment thread .kilo_workflow/e2e-start-resource.sh Outdated
Comment thread .kilo_workflow/await-role.sh Outdated
Comment thread .kilo_workflow/await-interactive.sh Outdated
@kilo-code-bot

kilo-code-bot Bot commented Jul 31, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

The incremental change (f24703be..576494c7, one doc file, 10 insertions / 3 deletions) only expands the Android emulator-start failure table and record-lifetime wording; every claim was verified against dev/local/mobile-android.ts, and the prior open suggestion is now resolved.

Previous finding re-verified on the changed lines
  • Resolved (was line 299): the attempt-2 GPU table now has rows for all pre-boot launch throws — exited during launch; see <log> (dev/local/mobile-android.ts:369), did not bind console port … within 30s; see <log> (:373), does not own console port … (:376), did not record its PID (:367) — plus a catch-all row, and line 306 states that only the boot-envelope timeout retries the Mac GPU.
  • Verified: "the session record … only exists after a successful launch bind" matches the write at :389-391, which happens after the pid/bind/ownership checks.
  • Verified: "pre-boot launch failures delete it before rethrowing" matches :415-417, and "emulator-stop still reaps a stray tmux session" matches the ENOENT branch at :288-291.
  • Verified: "boot-wait failures leave the record in place" — waitForAndroidBoot (:467, :479, :483) throws without touching the record, so the documented emulator-stop before relaunch is still required to avoid the "already exists" guard at :333-336.
  • Verified: "the path after see in the error text (when present)" is correct; did not record its PID and does not own console port … carry no log path.
Files Reviewed (1 file)
  • apps/mobile/e2e/AGENTS.md
Assumptions
  • Incremental scope: only f24703be..576494c7 was reviewed; findings on files unchanged in this range were not carried forward.
  • Read-only run: nothing was executed. Command, path, and error-string claims come from reading dev/local/mobile-android.ts.
  • No macOS/Android host was available, so the runbook was validated against wrapper source rather than an observed emulator failure.
  • Minor, not flagged: the did not record its PID row's cause text ("launch failed before pid file") is imprecise — a genuinely missing pid file surfaces as an ENOENT read error at :365, which the catch-all row already routes to software GPU.
Previous Review Summaries (8 snapshots, latest commit f24703b)

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

Previous review (commit f24703b)

Status: 1 Issue Found | Recommendation: Optional follow-up; safe to merge

Executive Summary

Both prior findings are fixed on the changed lines; the only remaining nit is that the new Android failure table maps GPU choice for the two boot-wait errors but not for emulator-start's pre-boot launch throws.

Overview

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

SUGGESTION

File Line Issue
apps/mobile/e2e/AGENTS.md 299 Error-text → attempt-2 GPU table covers only the two waitForAndroidBoot errors; the pre-boot launch failures (exited during launch, did not bind console port ... within 30s, does not own console port, did not record its PID — dev/local/mobile-android.ts:366-377) have no row, and those paths also delete the session record (:415-417) that line 306 suggests reading (inline comment posted)
Previous findings re-verified on the changed lines
  • Fixed (was line 300): attempt 2's GPU is now chosen from the error text before any teardown, and the text states explicitly that emulator-stop kills the PID and deletes the record. Both quoted error strings match source (dev/local/mobile-android.ts:467, :483), and the mapping (died while booting → swiftshader_indirect, boot-envelope timeout → retry host) is consistent with the policy at line 279.
  • Fixed (was line 39): grep -i slot over apps/mobile/e2e/AGENTS.md now returns nothing; the take/free-slot wording at former lines 32, 39, and 369 is gone and cleanup ends at pnpm dev:stop.
  • Verified: the log path $TMPDIR/kilo-e2e-android-<slug>.log and record path $TMPDIR/kilo-mobile-android-emulators/<slug>.json match androidEmulatorSession / emulatorRecordPath and the slug rule [^A-Za-z0-9_-] → _ (dev/local/mobile-android.ts:161-175, :340).
  • Verified: after a failed --wait, the record persists (only waitForAndroidBoot threw, :683-685), so the documented emulator-stop before relaunch is required — without it the next emulator-start throws "already exists" (:333-336).
Files Reviewed (1 file)
  • apps/mobile/e2e/AGENTS.md - 1 issue
Assumptions
  • Incremental scope: only bacd2037..f24703be (one file, 19 insertions / 13 deletions) was reviewed. Findings on files unchanged in this range were not carried forward.
  • Read-only run: nothing was executed. All command, path, and error-string claims come from reading dev/local/mobile-android.ts and package.json.
  • No macOS/Android host was available, so the runbook was validated against wrapper source rather than an observed emulator failure.

Fix these issues in Kilo Cloud

Previous review (commit bacd203)

Status: 2 Issues Found | Recommendation: Address before merge

Executive Summary

The new Android failure runbook tells the bundle owner to tear the emulator down before evaluating the GPU policy, which makes that policy always resolve to software rendering, and the slot instructions still describe tooling this PR deletes.

Overview

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

WARNING

File Line Issue
apps/mobile/e2e/AGENTS.md 300 New failure path orders emulator-stop before the "software GPU only when the process is gone" decision; the stop path kills the recorded PID and deletes the session record, so attempt 2 always picks software rendering, contradicting the policy at line 280 (inline comment posted)
apps/mobile/e2e/AGENTS.md 39 This PR deletes e2e-take-slot.sh / e2e-free-slot.sh / e2e-slot-status.sh, and this commit dropped "then take a slot" from line 34, but lines 32, 39, and 369 still instruct taking/freeing a slot with no remaining repo command (inline comment posted)
Previous findings re-verified on the changed lines
  • Fixed: line 228 teardown ordering now names pnpm dev:mobile:simulator release-all / pnpm dev:mobile:android emulator-stop; both subcommands exist (dev/local/mobile-simulator.ts:95-118, dev/local/mobile-android.ts:688-718) and the order matches the Cleanup block at lines 375-378.
  • Fixed: line 34 now says pnpm dev:stop (package.json:29) instead of the deleted e2e-stop-resource.sh stack.
  • Addressed: the --wait failure path is now documented. Verified against source — emulator-start prints JSON only after waitForAndroidBoot returns (dev/local/mobile-android.ts:681-687), the log path is os.tmpdir()/kilo-e2e-android-<slug>.log with slug = basename with non [A-Za-z0-9_-] replaced by _ (161-167, 340), and both quoted error strings match (467, 483).
  • grep over the worktree finds no remaining e2e-stop-resource, e2e-take-slot, or .kilo_workflow references.
  • emulator-stop is safe when the record is already gone (ENOENT path returns after killing a stray tmux session, dev/local/mobile-android.ts:281-292), so the new "then run emulator-stop" guidance does not itself fail on the early-launch failure path.
Files Reviewed (1 file)
  • apps/mobile/e2e/AGENTS.md - 2 issues
Assumptions
  • Incremental scope: only the aa7f7735..bacd2037 diff (one file, 11 added lines) was reviewed. Findings from earlier commits on unchanged files were not carried forward.
  • Read-only run: nothing was executed. All command, log-path, and error-string claims come from reading package.json, dev/local/mobile-android.ts, and dev/local/mobile-simulator.ts.
  • No macOS or Android device environment was available, so the runbook was validated against wrapper source rather than an observed emulator failure.

Fix these issues in Kilo Cloud

Previous review (commit aa7f773)

Status: 3 Issues Found | Recommendation: Address before merge

Executive Summary

The removal commit (6ccabc66..aa7f7735) leaves apps/mobile/e2e/AGENTS.md instructing agents to run e2e-stop-resource.sh, a script this PR deletes, so the runbook's teardown steps are now unrunnable.

Overview

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

WARNING

File Line Issue
apps/mobile/e2e/AGENTS.md 228 Teardown ordering still names the deleted e2e-stop-resource.sh ios|android (inline comment posted)
apps/mobile/e2e/AGENTS.md 34 "stop it through e2e-stop-resource.sh stack" also names a deleted script; the surviving equivalent is pnpm dev:stop. Summary-only: the line is outside this PR's diff hunks, so it is not inline-commentable

Both survived the PR description's rg '\.kilo_workflow' check because they omit the directory prefix.

SUGGESTION

File Line Issue
apps/mobile/e2e/AGENTS.md 283 emulator-start --wait prints its JSON only after a successful boot, so $EMULATOR_LOG is unset on the failure path that lines 295-300 tell the owner to report from (inline comment posted)
Verified on the changed lines
  • Replacement commands exist and match the wrappers: dev:env/dev:start/dev:status/dev:stop (package.json:28-34, dev/local/cli.ts:1086-1101), drizzle migrate (package.json:21), and dev:mobile:android emulator-start|emulator-stop|claim|build|release-all (dev/local/mobile-android.ts:681-716). --gpu host --wait is accepted by parseEmulatorStartArgs (dev/local/mobile-android.ts:440-458), and .serial/.pid/.log all exist on the emitted record.
  • The iOS snippet's JSON.parse(...).device.id matches the real claim payload (dev/local/mobile-simulator.ts:262, 581-592).
  • dev:env -y cloudflare-session-ingest and the dev:start target list (mobile cloud-agent-next kiloclaw event-service) all resolve through resolveTargets (dev/local/services.ts:793-810).
  • Deleting dev/local/workflow-scripts.test.ts drops no product coverage: it contained no record.sh assertions, and the retained dev/local/appium-wrapper.test.ts covers record.sh. No script, config, or CI file still references the deleted test, the seven removed .kilo/agent/* roles, or any .kilo_workflow path.
  • scripts/worktree-prepare.sh only loses the machine-local learnings copy; the surrounding env-file copy and direnv allow steps are untouched.
  • dev/local/mobile-simulator.ts changes are comment-only; claim concurrency still rests on atomic wx creation plus the per-device mutation lock, which does not depend on the removed external semaphore.
Files Reviewed (6 files, plus 82 deletions)
  • apps/mobile/e2e/AGENTS.md - 3 issues
  • apps/mobile/AGENTS.md
  • apps/mobile/e2e/remote-cli.sh
  • dev/local/mobile-simulator.ts
  • scripts/worktree-prepare.sh
  • dev/local/workflow-scripts.test.ts (deleted)
  • .kilo_workflow/** and .kilo/agent/*.md (deleted)
Assumptions
  • Incremental scope: only the diff from the previously reviewed commit was analyzed. Prior findings on apps/mobile/e2e/record.sh were not re-raised; that file is unchanged in this increment. Prior findings on dev/local/workflow-scripts.test.ts and .kilo_workflow/* are dropped because those files no longer exist at HEAD.
  • Read-only run: nothing was executed. Command-existence and payload-shape claims come from reading package.json, dev/local/cli.ts, dev/local/services.ts, dev/local/mobile-android.ts, and dev/local/mobile-simulator.ts.
  • No macOS/device environment was available, so the runbook was validated against wrapper source rather than an observed E2E run.

Fix these issues in Kilo Cloud

Previous review (commit 6ccabc6)

Status: No Issues Found | Recommendation: Merge

Executive Summary

The incremental change (f0ebadfe..6ccabc66, one file, 8 added lines) fixes the previously reported set -euo pipefail abort in record.sh stop's corrupt-state iOS reap, and no new changed-line issues were found.

Resolved since the previous review
  • apps/mobile/e2e/record.sh:294-301 — the previous CRITICAL is fixed. pgrep is now captured in a command substitution guarded by || true, so a no-match exit 1 no longer trips errexit/pipefail, and the subsequent printf | while read pipeline ends on a loop that returns 0. A blind stop with unreadable state now reaches clear_state and exit 0 as documented in the header contract (line 11) and relied on by bundle teardown.
Verified on the changed lines
  • [ -n "$orphans" ] guard prevents printf '%s\n' "" from feeding an empty line to kill; the inner [ -n "$orphan" ] || continue is a redundant but harmless second guard.
  • set -u is satisfied: orphans is always assigned before it is read.
  • pgrep -f "simctl io $DEVICE recordVideo" cannot self-match (pgrep excludes its own pid) and the enclosing record.sh <device> stop command line does not match the pattern, so the reap cannot SIGINT the script itself.
  • kill -INT (never SIGKILL) is preserved, and the pattern remains scoped to $DEVICE, so a sibling worktree's simulator recorder is not reaped.
  • The Android branch (lines 288-292) is unchanged and still exit-safe.
Files Reviewed (1 file)
  • apps/mobile/e2e/record.sh
Assumptions
  • Incremental scope only: the diff from the previously reviewed commit touches apps/mobile/e2e/record.sh alone, so unchanged files were not re-analyzed and no earlier finding from an unchanged file is carried forward.
  • Read-only run: no scripts, shells, or tests were executed. The exit-status conclusions are derived from set -euo pipefail (line 12), documented bash pipeline-status semantics, and pgrep's exit-1-on-no-match behavior.
  • No macOS/device environment was available, so runtime reap behavior rests on script contents rather than an observed run.
  • One read-only gh call (fetching the summary comment metadata) was rejected by the environment; the trusted summary comment ID from the review prompt was used for the update instead.

Previous review (commit f0ebadf)

Status: 1 Issue Found | Recommendation: Address before merge

Executive Summary

The new best-effort iOS reap in record.sh stop runs an unguarded pgrep pipeline under set -euo pipefail, so a corrupt-state stop with no live recorder now exits 1 without clearing state — the exact idempotency contract the commit was meant to preserve.

Overview

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

CRITICAL

File Line Issue
apps/mobile/e2e/record.sh 294 pgrep -f "simctl io $DEVICE recordVideo" exits 1 when nothing matches; pipefail + errexit abort the script before clear_state/exit 0 (lines 299-300), so blind stop returns 1 and leaves the unreadable state dir in place, breaking the documented idempotent-stop contract used by bundle teardown
Resolved since the previous review
  • apps/mobile/e2e/record.sh:286 — the carried-forward SUGGESTION (unreadable state cleared without any best-effort reap) is addressed: the stop corrupt-state path now attempts a device-wide adb shell pkill -INT screenrecord for emulator-* serials and SIGINTs matching simctl ... recordVideo processes for iOS UDIDs before clear_state. The implementation introduces the new CRITICAL above, but the original gap is closed.
Verified on the changed lines
  • Android branch (lines 288-292) is exit-safe: resolve_adb failure is consumed by the if condition, and pkill is guarded with || true, so a missing adb or absent recorder cannot abort stop.
  • Device-wide pkill -INT screenrecord is correctly scoped with -s "$DEVICE", so it cannot reap a sibling worktree's emulator.
  • kill -INT (never SIGKILL) is preserved on both paths, so a finalizing recorder still gets a chance to write its container.
Files Reviewed (1 file)
  • apps/mobile/e2e/record.sh - 1 issue
Assumptions
  • Incremental scope only: 115a8e1b..f0ebadfe touches apps/mobile/e2e/record.sh alone (14 added lines), so unchanged files were not re-analyzed and no other previous finding is carried forward.
  • Read-only run: no scripts, shells, or tests were executed. The pipefail/errexit conclusion is derived from set -euo pipefail on line 12, documented bash pipeline-status semantics, and pgrep's exit-1-on-no-match behavior, plus confirmation that dev/local/appium-wrapper.test.ts:322 reaches stop only with valid state.
  • No macOS/device environment was available, so recorder-liveness behavior rests on script contents rather than an observed run.

Fix these issues in Kilo Cloud

Previous review (commit 115a8e1)

Status: 1 Issue Found | Recommendation: Address before merge

Executive Summary

Incremental review of 3bb72dfa..115a8e1b found only an oxfmt reformat of the corrupt-state test (no behavior change, previous formatting finding resolved); the sole remaining open item is the unchanged record.sh stop path that clears unreadable state without a best-effort recorder reap.

Overview

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

SUGGESTION

File Line Issue
apps/mobile/e2e/record.sh 286 Unreadable state is cleared and stop exits 0 without attempting to SIGINT a possibly-live recorder; $DEVICE is still known, so a best-effort reap before clear_state keeps the idempotent contract without stranding a recording device (carried forward; verified still present at current HEAD, file unchanged this round)
Resolved since the previous review
  • dev/local/appium-wrapper.test.ts — the new corrupt-state test block is now oxfmt-clean: the 107-char fs.writeFileSync and spawnSync calls are wrapped (lines 331-334, 344-351) and the duplicate blank line before the test was removed. No line in the changed region exceeds printWidth: 100, and the wrapping matches the identical pattern already used at lines 300-307. The corresponding inline comment is now outdated on GitHub.
Verified on the changed lines
  • The single incremental commit (style: oxfmt corrupt-state record.sh test) is formatting-only: same spawnSync target, same argv (['UDID-C', 'start', video]), same env, same state fixture content (platform=not-valid-base64!!!\n) and same assertions. No behavioral change to the test, and no new bug, security, or error-handling risk introduced.
Files Reviewed (1 file)
  • dev/local/appium-wrapper.test.ts - 0 issues
Assumptions
  • Incremental scope only: 3bb72dfa..115a8e1b touches one file, so unchanged files were not re-analyzed; the record.sh item above was kept only after a targeted re-read confirming record.sh:283-288 is unchanged at HEAD.
  • Read-only run: no scripts, tests, or formatters were executed. The formatting resolution is derived from measured line lengths against .oxfmtrc.json (printWidth: 100) plus the surrounding oxfmt-produced wrapping style, not from an oxfmt run.
  • No device/macOS verification was possible, so recorder-liveness reasoning rests on script contents and documented bash/base64/simctl behavior.

Fix these issues in Kilo Cloud

Previous review (commit 3bb72df)

Status: 2 Issues Found | Recommendation: Address before merge

Executive Summary

Incremental review of cf5e4185..3bb72dfa (corrupt-state recovery in record.sh plus its new test) found no correctness defect in the recovery logic; the highest-value note is that the new unreadable-state stop path deletes state and exits 0 without any best-effort recorder reap, so teardown can report a clean device while a recorder is still live.

Overview

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

SUGGESTION

File Line Issue
apps/mobile/e2e/record.sh 286 Unreadable/pid-less state is cleared and stop exits 0 without attempting to SIGINT a possibly-live recorder; $DEVICE is still known, so a best-effort reap before clear_state keeps the idempotent contract without stranding a recording device
dev/local/appium-wrapper.test.ts 342 New test block is not oxfmt-clean (two 107-char lines vs printWidth: 100, plus consecutive blank lines at 321-322), so root format:check (oxfmt --list-different .) will fail
Verified on the changed lines
  • record.sh:226-235 — start now self-clears unreadable state instead of dying under set -e. The elif keeps the "already recording" guard for readable state, and the redundant second clear_state at line 236 is harmless. Guard bypass only applies to state that write_state cannot itself produce, so no reachable regression.
  • record.sh:283-292 — stop stays exit-0/idempotent for blind bundle cleanup. Loss of human-inspectable state is the tradeoff noted above; no new orphan path relative to the previous behavior, since a pid-less state was already a no-op.
  • appium-wrapper.test.ts:323-356 — the fixture (platform=not-valid-base64!!!) does make base64 -d fail on both GNU and BSD base64, so the test exercises the intended read_state failure branch and then asserts a full start/stop round trip.
Files Reviewed (2 files)
  • apps/mobile/e2e/record.sh - 1 issue
  • dev/local/appium-wrapper.test.ts - 1 issue
Assumptions
  • Incremental scope only: cf5e4185..3bb72dfa touches two files, so unchanged files were not re-analyzed and previously answered findings on unchanged code are not repeated.
  • Read-only run: no scripts, tests, or formatters were executed. The formatting finding is derived from measured line lengths against .oxfmtrc.json (printWidth: 100) and the root format:check script, not from an oxfmt run.
  • No device/macOS verification was possible, so recorder-liveness reasoning rests on the script contents plus documented bash, base64, and simctl/adb behavior.

Fix these issues in Kilo Cloud

Previous review (commit cf5e418)

Status: No Issues Found | Recommendation: Merge

Executive Summary

Incremental review of 72d88cc8..cf5e4185 covers only apps/mobile/e2e/record.sh; the commit makes b64_encode failure fatal in write_state, which resolves the previously reported orphaned-recorder path, and no new changed-code issues were found (high confidence).

Resolved since the previous review
  • record.sh:84-88 — write_state now captures the encode into encoded=$(b64_encode "$2") || return 1 before printf, so an encode failure aborts start instead of writing pid= and letting read_state's empty-pid guard trip after the recorder is already live (previous WARNING).
Files Reviewed (1 file)
  • apps/mobile/e2e/record.sh
Assumptions
  • Incremental scope only: the range 72d88cc8..cf5e4185 touches a single file, so unchanged files were not re-analyzed and previously answered findings on unchanged code are not repeated.
  • Read-only run: no scripts executed and no device/macOS verification, so the assessment rests on file contents plus documented bash semantics (an assignment

[Snapshot truncated.]

Additional previous summary content was truncated to keep this comment within platform limits.


Reviewed by claude-opus-5 · Input: 28 · Output: 5.5K · Cached: 553.8K

Review guidance: REVIEW.md from base branch main

Clear Android remote video before each segment, quote state values, verify
recorder PIDs, require simctl/adb success before DEAD checks, key android
prebuild skip on gradlew, and fixed-string match for --until-launched.
Comment thread apps/mobile/e2e/record.sh Outdated
Comment thread apps/mobile/e2e/record.sh
Comment thread apps/mobile/e2e/record.sh Outdated
Comment thread .kilo_workflow/e2e-slot-status.sh Outdated
Use untruncated ps -ww for recorder ownership, base64 state (no eval),
SIGINT before clear on failed start liveness, and note when simctl/adb
enumeration fails instead of printing a false all-clear.
Comment thread apps/mobile/e2e/record.sh Outdated
base64 encode/decode failures and empty pid no longer become silent
stop no-ops that orphan a live recorder.
Comment thread apps/mobile/e2e/record.sh Outdated
iscekic added 2 commits July 31, 2026 06:51
Capture b64_encode before printf so encode errors abort start instead of
writing an empty pid that turns stop into a silent no-op.
start clears unreadable state and continues; stop clears corrupt state
as an idempotent no-op so bundle teardown cannot strand a device.
Comment thread apps/mobile/e2e/record.sh
Comment thread dev/local/appium-wrapper.test.ts Outdated
iscekic added 2 commits July 31, 2026 07:07
On corrupt stop, SIGINT android screenrecord / matching iOS simctl
recordVideo before clearing state so blind cleanup cannot strand a device.
Comment thread apps/mobile/e2e/record.sh Outdated
Guard pgrep under set -e so blind stop still clears state and exits 0.
@iscekic iscekic added the human-ready The PR is ready for human review. label Jul 31, 2026
@iscekic
iscekic enabled auto-merge (squash) July 31, 2026 06:17
Remove the shared multi-agent workflow from the monorepo so colleague agent
pools are not polluted by personal automation, learnings, and role agents.

- Delete .kilo_workflow/ (scripts, WORKFLOW.md, learnings) and the seven
  workflow role agents under .kilo/agent/
- Drop dev/local/workflow-scripts.test.ts (tested the removed scripts)
- Stop worktree-prepare from copying workflow system learnings
- Rewrite mobile e2e runbook / AGENTS / remote-cli / simulator comments to use
  pnpm dev helpers only — no .kilo_workflow paths remain in the tree

The workflow continues at ~/Projects/.kilo_workflow (local git repo; agents
under .kilo/agent/). Product E2E helpers (record.sh, appium multi-flow) stay.
@iscekic iscekic changed the title fix(workflow): harden E2E slots, verifier efficiency, control plane chore: remove .kilo_workflow from monorepo (machine-local) Jul 31, 2026
Comment thread apps/mobile/e2e/AGENTS.md Outdated
Comment thread apps/mobile/e2e/AGENTS.md
…ed --wait logs

Kilobot on PR #4909:
- record.sh teardown order named e2e-stop-resource.sh, deleted by this PR
- emulator-start --wait leaves $EMULATOR_LOG unset on failure; document the
  deterministic $TMPDIR log path and error-text path instead
Comment thread apps/mobile/e2e/AGENTS.md Outdated
Comment thread apps/mobile/e2e/AGENTS.md Outdated
Kilobot on PR #4909:
- Decide attempt-2 GPU from the emulator-start error text before teardown;
  emulator-stop kills the PID and deletes the session record, so "process gone
  after stop" always looked like a dead-PID failure
- Remove remaining take/free "slot" language; slot tooling left the monorepo
Comment thread apps/mobile/e2e/AGENTS.md
Kilobot suggestion: attempt-2 GPU table only covered the two boot-wait
errors. Pre-boot launch throws (exited during launch, port bind timeout,
foreign port, missing PID) also mean the host-GPU path failed — treat them
like a dead PID and use swiftshader. Note pre-boot paths delete the session
record before rethrowing.
@iscekic
iscekic merged commit 0a1e407 into main Jul 31, 2026
22 checks passed
@iscekic
iscekic deleted the workflow-hardening-ceec branch July 31, 2026 07:08
iscekic added a commit that referenced this pull request Jul 31, 2026
Main deleted all of .kilo_workflow in #4909; the workflow now lives in a
private repo. Remove the branch learning that survived the merge (already
ported there) so the PR carries zero workflow diffs.
iscekic added a commit that referenced this pull request Jul 31, 2026
…costs (#4884)

* fix(mobile): keep screen awake while agent works; animate subagent sheet dismiss

Install expo-keep-awake and mount a conditional useKeepAwake host while
the session is streaming or has pending messages, so the idle timer
stays off exactly while the UI shows the agent as working (item 15).

Mount the child session sheet behind a separate visible flag instead of
unmounting it on close, so iOS plays the native slide-down animation
instead of flashing the white window behind (item 21).

* docs(mobile): reference kilo-design baseline in AGENTS.md (item 12)

* fix(mobile): show Older activity residual in session context sheet

Reconcile the persisted page total against the live cost breakdown when
history is unpaginated: an Older activity row carries the residual
exactly when it exceeds the 1 microdollar epsilon, so Total always
matches the visible rows (item 23).

* fix(mobile): disable native text selection inside message bubbles

Gate selectable behind InMessageBubbleContext so a long-press anywhere
in a message opens the details sheet without the iOS selection callout
floating over it (item 13). Preparation group and child-sheet texts
keep native selection as their only copy path; details-sheet copy and
the a11y rotor path are unchanged.

* fix(mobile): slash menu separators + SheetHeader title ellipsis

Use the border-border theme token between slash-command rows and drop
the trailing separator (item 24). Bound sheet titles in a flex-1 px-24
wrapper with numberOfLines=1 so long titles ellipsize without covering
the Done/Cancel controls, which render after the title to stay on top
(item 25).

* fix(mobile): composer AppState restore, swipe-down dismiss, reliable growth

Move message-input-app-state to src/lib as the shared home and reuse
its blur-on-background / delayed-refocus pattern in the agents composer
(item 19). Replace the hidden mirror-Text measurement with the
TextInput's own onContentSizeChange plus pure, unit-tested reducers, so
the composer reliably grows to its max height then scrolls (item 26).
Add a downward-pan GestureDetector scoped to the composer input row so
a swipe down dismisses the keyboard when the input is not scrollable
(item 22).

* docs(workflow): learning — CLI sessions read-only until TUI /remote relays them

* fix(mobile): restore mirror-Text composer growth (item 26)

iOS Fabric emits TextInput onContentSizeChange only from
updateLayoutMetrics, so a fixed-height uncontrolled input never
reports growth past the initial layout — the onContentSizeChange
reducers could never grow the composer. Restore the mirror-Text
measurement (useTextHeight), which follows JS text state
deterministically and was iOS-proven on this composer. Keep the pure
scroll-threshold helper; AppState focus restore (item 19) and
swipe-down dismiss (item 22) unchanged.

* fix(mobile): dismiss keyboard on Android EditText swipe-down (item 22)

ReactEditText requests disallow-intercept on every ACTION_DOWN, so the
wrapper's RNGH pan never sees the stream start from the focused input.
Track bubbled JS touch moves on the composer host View and dismiss at
the same 24px threshold, claiming the responder there. Android-only;
the iOS RNGH path is unchanged.

* fix(mobile): evaluate composer AppState refocus gate at fire time (item 19)

The effect's [disabled, isSending] deps let any flip re-run the effect
and clear the pending 100ms focus restore after 'active' had already
consumed the restore flag — Android intermittently (5/16 cycles) never
restored the composer keyboard. Subscribe once, schedule unconditionally
on shouldFocus, and gate on live refs at fire time.

* chore: drop .kilo_workflow remnants after main merge

Main deleted all of .kilo_workflow in #4909; the workflow now lives in a
private repo. Remove the branch learning that survived the merge (already
ported there) so the PR carries zero workflow diffs.

* fix(mobile): restore copy path for tool output and reasoning (item 13)

In-bubble native selection was disabled so the iOS callout cannot float
over the details sheet, but both remaining copy paths (details-sheet Copy
message, a11y rotor) collect only text parts — tool commands/outputs/
errors and reasoning lost their only copy route. Extend
collectCopyableText to serialize reasoning and tool parts; parts with no
payload yet stay excluded.

Addresses Kilobot thread on mono-scroll-block.tsx.

* fix(mobile): bound child-sheet mount and keep-awake to their lifetimes

Child sheet (item 21): the mounted-during-close pattern exists only to
let the native dismiss animation play, but the sheet identity lived on
for the rest of the screen, running child-transcript scans on every
streaming render. Release it 350ms after close (covers the animation;
the white flash is iOS-specific); a reopen before the release wins and
a visible sheet is never released.

Keep-awake (item 15): gate on useIsFocused so a screen covered by a
pushed route stops holding the OS idle timer, and scope the expo tag by
session id so stacked session screens cannot release each other's wake
lock.

Addresses two Kilobot threads on session-detail-content.tsx +
child-session-sheet-state.ts.

* fix(mobile): suppress sub-display Older-activity residuals (item 23)

The 1µ$ reconciliation epsilon let 2-49µ$ residuals render an
"Older activity $0.0000" row. Gate on what formatCost actually
displays, mirroring formatSessionTotalCost's suppression, and reword
the subtitle — the residual also absorbs ingest gaps when the full
history is loaded.

Addresses Kilobot thread on session-cost-breakdown.ts.

* fix(mobile): scope Android swipe-dismiss touch tracking by identifier (item 22)

topTouch* events fire per changed touch: a second finger overwrote the
tracked gesture origin or reset it mid-drag, breaking the primary
finger's swipe-to-dismiss. Track nativeEvent.identifier and ignore
other identifiers, matching the RNGH pan's identifier awareness.

Addresses Kilobot thread on chat-composer.tsx.

* fix(mobile): release child sheet after iOS dismiss

* fix(mobile): stop keep-awake after disconnect
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

human-ready The PR is ready for human review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants