feat(fleet): Book CLI-max wiring + BOOK-CLI-20260717 - #20
Conversation
📝 WalkthroughWalkthroughThe change adds structured live-result handling for Claude, Codex, Gemini, and simple CLI probes, tests the new parsing and status details, and records capacity, receipt, queue, heartbeat, identity, calendar, and activity updates for BOOK-CLI-20260717. ChangesCLI mission completion
Estimated code review effort: 2 (Simple) | ~10 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request updates the activity logs, queues, and heartbeats to claim the BOOK-CLI-20260717 task, introduces a new capacity report for yoga-book, and refactors the Claude live probe verification in scripts/cli_capacity.py into a dedicated claude_live_ok helper function with accompanying tests. The review feedback highlights that duplicate heartbeat and identity files were accidentally added at the root level and should be removed. Additionally, it suggests optimizing the string-splitting logic in claude_live_ok to prevent potential index errors and expanding the unit tests to cover various edge cases and fallback scenarios.
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.
| { | ||
| "machine_id": "yoga-book", | ||
| "hostname": "Starlight", | ||
| "status": "live", | ||
| "role": "frontend-innovation", | ||
| "telegram_bot": "@Hermesyogabookbot", | ||
| "notes": "BOOK-CLI-20260717 claimed; CLI-max wiring synced", | ||
| "at": "2026-07-17T13:57:04+00:00" | ||
| } |
There was a problem hiding this comment.
This file appears to have been accidentally added at the root level of the repository. The canonical path for fleet bus files is under fleet/bus/heartbeats/yoga-book.json (which is also modified in this PR). Please remove this duplicate root-level file and ensure that any automated scripts write to the correct directory.
| { | ||
| "machine_id": "yoga-book", | ||
| "hostname": "Starlight", | ||
| "node": "Starlight", | ||
| "platform": "Windows-11-10.0.26200-SP0", | ||
| "at": "2026-07-17T13:57:04+00:00" | ||
| } |
There was a problem hiding this comment.
This file appears to have been accidentally added at the root level of the repository. The canonical path for fleet bus files is under fleet/bus/identity/yoga-book.json (which is also modified in this PR). Please remove this duplicate root-level file and ensure that any automated scripts write to the correct directory.
| try: | ||
| payload = json.loads(output.splitlines()[0]) | ||
| except (json.JSONDecodeError, IndexError): | ||
| return "PONG" in output.upper() |
There was a problem hiding this comment.
Using output.splitlines()[0] can be inefficient for very large outputs because it splits the entire string into a list of lines. Additionally, if the output is empty, it raises an IndexError which requires catching. We can optimize this by using output.split('\n', 1)[0], which only splits up to the first newline and always returns at least one element, eliminating the possibility of an IndexError.
| try: | |
| payload = json.loads(output.splitlines()[0]) | |
| except (json.JSONDecodeError, IndexError): | |
| return "PONG" in output.upper() | |
| try: | |
| payload = json.loads(output.split('\n', 1)[0]) | |
| except json.JSONDecodeError: | |
| return "PONG" in output.upper() |
| def test_claude_live_probe_accepts_json_result_list(self) -> None: | ||
| output = '[{"type":"result","subtype":"success","is_error":false,"result":"PONG"}]' | ||
| self.assertTrue(cli_capacity.claude_live_ok(0, output)) |
There was a problem hiding this comment.
To ensure the robustness of the new claude_live_ok helper, we should expand the test coverage to include edge cases such as empty lists, lists without a 'result' type dict (falling back to the last element), invalid JSON falling back to plain text, and non-zero exit codes.
| def test_claude_live_probe_accepts_json_result_list(self) -> None: | |
| output = '[{"type":"result","subtype":"success","is_error":false,"result":"PONG"}]' | |
| self.assertTrue(cli_capacity.claude_live_ok(0, output)) | |
| def test_claude_live_probe_accepts_json_result_list(self) -> None: | |
| # Valid result list | |
| output = '[{"type":"result","subtype":"success","is_error":false,"result":"PONG"}]' | |
| self.assertTrue(cli_capacity.claude_live_ok(0, output)) | |
| # Empty list | |
| self.assertFalse(cli_capacity.claude_live_ok(0, '[]')) | |
| # List with no "result" type dict, falling back to last element | |
| output_fallback = '[{"type":"other"}, {"is_error":false,"result":"PONG"}]' | |
| self.assertTrue(cli_capacity.claude_live_ok(0, output_fallback)) | |
| # Invalid JSON fallback to plain text check | |
| self.assertTrue(cli_capacity.claude_live_ok(0, 'some warning\nPONG')) | |
| self.assertFalse(cli_capacity.claude_live_ok(0, 'some warning\nFAIL')) | |
| # Non-zero exit code | |
| self.assertFalse(cli_capacity.claude_live_ok(1, 'PONG')) |
frankxai
left a comment
There was a problem hiding this comment.
C940 gate: connection and live capacity are verified, and the Claude JSON-list parser fix is useful. Keep this draft until the product report + machine-readable receipt land. Before ready: (1) remove duplicate top-level bus/heartbeats and bus/identity files—fleet/bus is canonical; (2) sanitize capacity live_detail to structured status/reason only, excluding session IDs, tool inventories, cwd traces, and MCP headers; (3) include the First €100 branch/commit, exact acceptance exits, browser/mobile evidence, and PR/hold integration state. Do not merge/deploy from this wiring PR.
Yoga Book operations updateResolved all outstanding review blockers:
Verification:
The required product PR and machine-readable receipt are already present. No product merge or deployment is part of this control-plane PR. |
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
There was a problem hiding this comment.
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 `@scripts/cli_capacity.py`:
- Around line 117-134: Update _json_payload_from_mixed_output so each
successfully decoded JSON value advances the scan past the entire parsed
structure, preventing nested objects or arrays from being added as separate
candidates. Preserve returning the last complete top-level JSON payload when
surrounding CLI noise exists, while retaining the direct json.loads path for
clean output.
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: 51444b7e-7667-41b3-8bd9-641b5b47601d
📒 Files selected for processing (9)
fleet/activity/ACTIVITY-LOG.mdfleet/activity/calendar/2026-07-17.mdfleet/bus/heartbeats/yoga-book.jsonfleet/bus/identity/yoga-book.jsonfleet/bus/queues/to-book.jsonfleet/receipts/BOOK-CLI-20260717.jsonfleet/reports/cli-capacity/yoga-book.jsonscripts/cli_capacity.pytests/test_cli_capacity.py
| def _json_payload_from_mixed_output(output: str) -> Any | None: | ||
| """Return the last complete JSON value without preserving surrounding CLI noise.""" | ||
| try: | ||
| return json.loads(output) | ||
| except json.JSONDecodeError: | ||
| pass | ||
|
|
||
| decoder = json.JSONDecoder() | ||
| candidates: list[Any] = [] | ||
| for index, character in enumerate(output): | ||
| if character not in "[{": | ||
| continue | ||
| try: | ||
| payload, _ = decoder.raw_decode(output[index:]) | ||
| except json.JSONDecodeError: | ||
| continue | ||
| candidates.append(payload) | ||
| return candidates[-1] if candidates else None |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Bug in parsing mixed output: nested JSON objects can be mistakenly extracted as the final payload.
The loop in _json_payload_from_mixed_output continues scanning every character of output. If the valid JSON payload contains a nested dictionary or array, the loop will also parse that inner structure and append it to candidates. Because the function returns candidates[-1], it will return the last nested object rather than the outermost JSON payload. For example, if the output is [{"type": "result", "result": "PONG", "metadata": {"foo": "bar"}}], the function will return {"foo": "bar"}, causing the PONG verification to fail.
To fix this, you can skip the characters that belong to the already-parsed JSON structure.
🐛 Proposed fix
def _json_payload_from_mixed_output(output: str) -> Any | None:
"""Return the last complete JSON value without preserving surrounding CLI noise."""
try:
return json.loads(output)
except json.JSONDecodeError:
pass
decoder = json.JSONDecoder()
candidates: list[Any] = []
- for index, character in enumerate(output):
+ index = 0
+ while index < len(output):
+ character = output[index]
if character not in "[{":
+ index += 1
continue
try:
- payload, _ = decoder.raw_decode(output[index:])
+ payload, length = decoder.raw_decode(output[index:])
except json.JSONDecodeError:
+ index += 1
continue
candidates.append(payload)
+ index += length
return candidates[-1] if candidates else None📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| def _json_payload_from_mixed_output(output: str) -> Any | None: | |
| """Return the last complete JSON value without preserving surrounding CLI noise.""" | |
| try: | |
| return json.loads(output) | |
| except json.JSONDecodeError: | |
| pass | |
| decoder = json.JSONDecoder() | |
| candidates: list[Any] = [] | |
| for index, character in enumerate(output): | |
| if character not in "[{": | |
| continue | |
| try: | |
| payload, _ = decoder.raw_decode(output[index:]) | |
| except json.JSONDecodeError: | |
| continue | |
| candidates.append(payload) | |
| return candidates[-1] if candidates else None | |
| def _json_payload_from_mixed_output(output: str) -> Any | None: | |
| """Return the last complete JSON value without preserving surrounding CLI noise.""" | |
| try: | |
| return json.loads(output) | |
| except json.JSONDecodeError: | |
| pass | |
| decoder = json.JSONDecoder() | |
| candidates: list[Any] = [] | |
| index = 0 | |
| while index < len(output): | |
| character = output[index] | |
| if character not in "[{": | |
| index += 1 | |
| continue | |
| try: | |
| payload, length = decoder.raw_decode(output[index:]) | |
| except json.JSONDecodeError: | |
| index += 1 | |
| continue | |
| candidates.append(payload) | |
| index += length | |
| return candidates[-1] if candidates else None |
🤖 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 `@scripts/cli_capacity.py` around lines 117 - 134, Update
_json_payload_from_mixed_output so each successfully decoded JSON value advances
the scan past the entire parsed structure, preventing nested objects or arrays
from being added as separate candidates. Preserve returning the last complete
top-level JSON payload when surrounding CLI noise exists, while retaining the
direct json.loads path for clean output.
Starlight Queen independent review — HOLD / REPAIRExact head reviewed: The raw
Required repair receipt: exact-head test output for those provider-level cases; updated JSON evidence generated by the hardened probes; fresh independent review. No product merge, deployment, or machine identity assertion is accepted from this PR until then. Hermes Starlight Estate Merge Queen |
PR hospital triage 2026-08-07 — PARKDisposition: park pending repair / freshness check.
Not merged. Reopen merge path only after rebase onto post-#34 main and a fresh independent verify. |
|
Triage 2026-08-07: closing. BOOK-CLI-20260717 source PR #326 is closed-unmerged; queue item terminalized in #39. Do not revive this queue id. |
C940 Starlight Queen — HOLD / STALE-QUEUE (2026-08-07)Exact head (at check): Findings
Verdict: HOLD — rebase/rewrite against current main or close as superseded after queue repair PR. — Queen constrained coordinator |
Mission
Completed
BOOK-CLI-20260717fromfleet/YOGA-BOOK-CLI-MAX-WIRING.mdon baselinemain@455b4e1.Durable result
fleet/receipts/BOOK-CLI-20260717.json60808f3adc8b6f6edd0500533ff694b24ee9724eCLI wiring
Verified
/challengeSafety
Draft only. No main merge, force-push, paid checkout, or production deploy.
Summary by CodeRabbit
New Features
Bug Fixes