Fixes from the 2026-10-13 review: metrics, General menu, event loop, code health #1
Loading…
Reference in a new issue
No description provided.
Delete branch "vinny/improvements"
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?
Fixes and code improvements from a review of CMOnet on 2026-10-13: the live controller's metrics, the General's tool menu, event-loop blocking, and code health.
Base note: local
masteris 24 commits ahead oforigin/master(a4d92cb). This branch builds on local master, so the PR also carries those commits (eef6662and earlier, already committed by the operator). The commits that belong to this PR are the last three.Metrics and menu (
51d26af)submitted_atwhen it starts running (agents/queue.py). All 3,794 requests in the operator's store were builder calls, and none were timed. Flows also recordduration_seconds.unresolved_blockingandunresolved_archived_expiredare reported separately, and there is a Prometheus gauge.outcome_unknownactions from 20–26 September. They no longer block anything and can never be read back.operations.reviseor resource reservations.execute()refused those calls, and the live order tests c and m hit this.requires_hierarchy().Event loop, world delivery metric and General guidance (
d7ce74c)written_at, and the probe times frames from that.world_changesinserts now share one helper.groups.remove_unitswhen the menu offers it.doctrine.set_valueguidance tells the model to checkplayer_editablefirst. A real model set a locked weapons-control status twice per run.api()reports an HTML or text error page as anApiErrorinstead of a JSONSyntaxError.Code health (
0289dab)domain/ports.pyplanning.geodesy.distance_nm/bearing_deg. The tester's byte copies and the builder'sgeomodule are unchanged.trusted_schema=OFF,query_onlyand no attached databases, as the catalog service does.config/example.settings.jsonlists all 63 settings. It was missing 13, and a test now requires every field, in order.config/environment.exampledocuments the TLS, provider CA bundle, proxy token, builder database/import folder and watchdog variables. A test checks that it names every variable the code reads.RUNTIME_HARDENING.md: the new metric fields and the 30 s busy timeout.AI_AGENT_TOOL_CATALOG.md: no longer claims the game writes are fail-closed in controlled mode.Verification
python tools/check.py(native Lua 5.4) on the branch:0289daband the test file re-run (95 passed). Evidence, registry and contract checks were then re-run, all clean.python -m cmonet --checkpassesThe baseline before these changes was 2,209 passed and 3 skipped.
No CMO actions were taken. The live controller was touched only by read-only API queries and a read-only SQLite connection.
Not in this PR
The larger items are filed as issues:
🤖 Generated with Claude Code
Live 2026-10-10 "an airbase at Diego Garcia, protected by anti air, with tankers, 24 F-22s and bombers" in a drawn Indian Ocean area put the bombers at Thumrait in Oman, outside the area, gave the F-22s the side's F-15EX, and placed the tankers, fighters and their SAMs nowhere; each retry added more. - The change patch takes a base (`based_at`), a named type per role (`class`) and a side. A named airfield becomes the side's base, its land a host nation when no hostile side holds it; an operating area that is an airfield bases a new package's aircraft too. - Bases chosen in code stay inside the package's strict drawn area. - A named type is looked up among the role's classes ("B-2" is the B-2A, not the B-21) instead of the side's class chosen before. - SAM, gun and ground units in an aircraft package become a package of their own at its base; a model's "air base" kind is never code's. - An area's change includes its packages placed nowhere or based outside it, so a request can replace an earlier one's; bases left empty go. - Sites keep 0.3 nm (not 1.5) off base structures and search a small island's land closer, so Diego Garcia holds its air defence. - The page lists the packages a change could not place in full. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>On the operator's game (Iran vs WORLD, side Iran: 1,435 own units, 3,522 contacts) collection kept pausing with "contacts lost its validated response after submission (proxy_error)". Collector 4.1.13 read every contact in one request: 3 MB in 4.3-5.8 s, and CMO's socket stops a command after 5.0 s of Lua execution ("elapsed-time budget exceeded"). Each automatic resume read them again and hit the limit again, holding the game thread about 5 s a time. Collector 4.1.14: - Contacts come a page at a time, in GUID order, from side.contacts (37 ms for 3,522 plain {guid,name} tables; ScenEdit_GetContacts builds a wrapper per contact first, 1.4 s), each fetched by GUID with ScenEdit_GetContact. A page of 256 costs 0.37 s of game time (proxy HEALTH). ScenEdit_GetContacts stays the fallback when the side's list can't be read; a listed contact the getter doesn't return is reported, never taken as gone. - The units collector (when a unit is firing) and the missions collector scope contact links with side.contacts too: missions went from 2.35 s to 87 ms of game time. - Contact pages adapt like own-unit batches but under their own ceiling, not the own-unit one, and a slow round trip stops halving them at 32. - One cycle of pages completes the contact baseline although contacts come and go between pages; the last page's list decides which are gone. The priority burst covers the whole cycle and starts on a known contact's posture or classification change or a new hostile one, not on churn alone. - The proxy's exact budget-abort reply is proxy_budget_exceeded. CMO stopped that script, so a read of several records is followed by one half its size instead of a pause; a second stop in a row, or a read that can't be smaller, pauses as before. Writes are never treated this way. - ScenEdit_GetContact joins the adapters' reviewed reads (it was reviewed for flow bundles); the G2 goldens are regenerated for it. Live measurements: docs/verification/LARGE-SCENARIO-CONTACTS-2026-10-11.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>- The inspector's CMO Missions and Attention Center panels fold to their headings; a selected unit then gets about twice the room. Each browser remembers the folds. - The map roster has kind chips with counts (own forces, contacts, missions, reference points) over its ~5,000 alphabetical records. - Settings folds the advanced socket/transport fields and the load-protection limits into groups; host and port stay in view, and a group opens if one of its fields is invalid. - Staff Views are tiles instead of five full-width cards; "1 roles" reads "1 role". - An inline favicon (the page asked for /favicon.ico on every load and got a 404). - A composite whose steps were all refused for one reason now says it ("No dependency-plan primitive completed: A mission-level game action requires a current order..."), so a model reading the top line learns why (live 2026-10-11, navigation.go_to). - README and the operator guide name the pages as the sidebar now does and describe the grouped sidebar, focus pages and folding. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>