Commit Graph

523 Commits

Author SHA1 Message Date
operator-main 3d5fbe5aeb NODES.md: mark ghost nodes def, dev inactive
The unassigned def/dev nodes were being iterated every 5 min by
agent-health.sh (via netvm-registry.py active_nodes()), producing a
perpetual FAIL -> kill -9 -> CRITICAL loop since they can never
"recover". fleet-alert-check.sh iterates the same registry, so this
also stops ghost-node alert noise. The dev registry row itself came
from another session's uncommitted work; this commit keeps their row
and marks it inactive rather than provisioning a node nobody asked
for.

Session: sidechat/chromebox-fixes
2026-10-04 22:47:25 +00:00
operator-main 76f854da6b Harden agent-health.sh: soften API-timeout kill path, add recent-relaunch guard
- Require 2 CONSECUTIVE muse-chat-api.py API failures before kill -9
  (per-node counter in /tmp/agent-health-state, reset on success).
  A single 30s API timeout killed 646s healthy browser at 20:48:44 UTC
  while its CDP port was still listening.
- Extend post-restart re-check grace to ~60s (15s internal + 45s), matching
  chromebox-watchdog.shs proven 60s retry window.
- Add recent_relaunch() guard (mirrors chromebox-watchdog.sh idiom):
  skip the kill path when the main browser process launched <2 min ago,
  so the two watchdogs can not kill each others fresh browsers.
- check_agent now returns 0/1/2 (healthy/api-fail/port-down); CDP-port
  failure still kills immediately. warp-$node checks untouched.

Session: sidechat/chromebox-fixes
2026-10-04 22:46:44 +00:00
operator 5984e374ce docs(onboarding): document hard /access edge gate resolution via Meta Accounts Center and activate dev node 2026-10-04 22:43:27 +00:00
operator-main f5d92467c4 bin/muse-threads.py: JSON-contract thread bookkeeping over muse-cli-node
Wraps session-pin/unpin/archive/unarchive/rename + threads in the per-agent hybrid gateway transport (netns-isolated, auto-refreshing cookies). Emits the {ok,code,error} contract server.py needs; validates agent/thread/title; never prints secrets, never uses a shell.

Session: sidechat/muse-cli-threads-helper
2026-10-04 22:35:30 +00:00
operator 178ddc5dbf feat(cred): harden client onboarding with Instagram linking portal, age verification bypass, and fleet runbook 2026-10-04 21:43:32 +00:00
operator-main 7902622852 dm.py: autoprovision creation check — refuse to adopt parked/already-mapped thread UUIDs (fixes 2026-10-04 heartbeat misroute) 2026-10-04 21:16:50 +00:00
operator-main 1e82f3adba Document 2026-10-04 followup fix set in LOOP-MANAGEMENT.md (backfill semantics, final_nudge_target, placement gate, multi-RESULT) 2026-10-04 20:09:56 +00:00
operator-main 5ab157b3b0 fleet alerting: fix netns naming in agent-health.sh + add fleet-alert-check.sh
agent-health.sh used bare node names for 'ip netns exec' but netns are

named warp-<node> since the NetVM layout; the 6189793 CDP-liveness check

always failed ('No such file or directory'), logging false CRITICALs and

kill -9'ing healthy browsers every 5 min. Use warp-$node.

fleet-alert-check.sh: new 5-min critical-condition detector (per-node CDP

liveness via warp-<node> netns). Consecutive-failure state machine:

page after 2 consecutive failures, re-page every 30 min while critical,

quiet-hours-aware (first alert always pages). Emits ALERT/RECOVERY

records to ~/.local/share/fleet-alert/outbox.jsonl for the container

fleet-alert-relay hook; best-effort box-ctl notify to healthy agents.

Session: sidechat/critical-alerting-pipeline
2026-10-04 20:09:36 +00:00
operator-main 8bb64c4826 Restore executable bit on sweeper/harvester (dropped by atomic mv) 2026-10-04 20:07:06 +00:00
operator-main ad9dbca7eb Restore followup/DM reliability fixes wiped by 19:43Z tree-clean
Re-applies three workstreams lost when 793d3d7 committed over uncommitted
edits, reconciled against the parallel track's committed dm.py changes:
- followup-sweeper.py: backfill thread_uuid after successful nudge sends;
  record final_nudge_target=main on final-nudge routing (C1/C2)
- response-harvester.py: resolve followups on main-chat replies when
  final_nudge_target=main (C3); harvest ALL [RESULT] markers per message
- dm.py: pre-send placement gate (fail closed when post-nav URL lacks the
  target thread UUID; skips main) — purely additive over 793d3d7+f268d3d
- sidechat_manager.py: wait_for_chat_list() settle-poll for list population
  race (sidebar button renders before titles load)
- new: bin/tests/test_followup_fixes.py (25 tests), bin/placement-audit.py,
  bin/dm-log-taxonomy.py, bin/session-probe.py,
  docs/SIDECHAT-RELIABILITY.md, docs/UUID-ROTATION.md

Verified: 25/25 tests pass, py_compile clean, sweeper/harvester dry-runs clean.
Known limitation: gate catches wrong-placement, not wrong-mapping (false
autoprovision adopting the parked thread needs a creation check).
2026-10-04 20:06:58 +00:00
box-ctl b5c5e2ff4c Add job mainloop-p1-pilot via box-ctl 2026-10-04 20:02:09 +00:00
box-ctl 7bbd48c459 Add job mainloop-p2-noswitcher via box-ctl 2026-10-04 20:02:09 +00:00
box-ctl 6b1ce53a1c Add job mainloop-p3-bridge via box-ctl 2026-10-04 20:02:09 +00:00
box-ctl 5c6b931caf Add job mainloop-p4-steady via box-ctl 2026-10-04 20:02:02 +00:00
operator-main f268d3d64b Harden dm.py sidechat navigation (CDP event drain + Page.navigate)
- ev(): drain CDP events until response id==1 (was blind recv,
  same bug class as box-chat-cdp.py 8d4bfa7 NO_SWITCHER fix)
- cmd_sidechat_use UUID path: use CDP Page.navigate instead of
  window.location.href via evaluate; 5 attempts, 15s SPA settle
  per attempt (was 3x4s, flaked 1/3 on url_mismatch)
- cmd_sidechat_use name path: retry 3x if not landing on /thread/

Test: 2/2 DM sends succeeded when browser healthy (tests 3-5
hit 646 browser death mid-test, infra issue not nav issue).

Session: sidechat/chromebox-ops
2026-10-04 19:47:33 +00:00
operator-main c59d492d49 Restore executable bit on bin/dm.py
Session: sidechat/chromebox-ops
2026-10-04 19:43:30 +00:00
operator-main 793d3d78d7 Remove hardcoded sidechat UUIDs from dm.py (heartbeat, 646-opm-work)
Thread UUIDs rotate -- heartbeat-opm died twice in one day
(5bd5b350 -> 0077e918 -> dead), dropping self_main_loop digests.
SIDCHAT_ALIASES is now intentionally empty; targets fall through to
job-sidechats.json dynamic mappings then name-based sidechat use with
autoprovision, which self-heals. Also removed stale heartbeat-opm and
pipe-9735f2 entries (dead UUID 0077e918) from job-sidechats.json.

Test: dm.py send to heartbeat resolved via name and SENT+VERIFIED
(thread 5f18476d-8994-49e7-a9e0-4838732363fe).

Session: sidechat/chromebox-ops
2026-10-04 19:43:04 +00:00
operator-main 18db8ff80b Fix self_main_loop exit code, [!] false positive, state race
- Exit 0 on success (was 1 when prompts sent, confusing systemd)
- [!] flag now uses word-boundary regex excluding hyphenated
  identities (operator-646 no longer triggers; 'operator needed' does)
- State writes now hold fcntl exclusive lock with fresh reload,
  preventing timer check from clobbering enable/disable changes

Session: sidechat/chromebox-ops
2026-10-04 19:39:50 +00:00
operator-main fcdee95dd6 chore: ignore pycache and runtime state files 2026-10-04 19:26:11 +00:00
operator-main 5121dde90e fix: drop stale hardcoded sidechat UUID, use job-sidechats.json mapping
- bin/dm.py: remove 646 tasks -> 1e75a740 from SIDCHAT_ALIASES. That UUID is stale (not a valid thread on 646 account; SPA redirects elsewhere, causing misdelivery). Alias now falls through to job-sidechats.json/autoprovision. Do NOT re-add hardcoded UUIDs.

- job-sidechats.json: live autoprovisioned mappings for 646-pip and 646 tasks (2026-10-04).

- bin/box-chat-cdp.py: CDP robustness -- drain events until command response, retry switcher lookup while SPA settles, fresh reconnect per retry (transient NO_SWITCHER on pip/opm 2026-10-04).

Session: sidechat/uuid-stale-fix
2026-10-04 19:02:35 +00:00
operator-main 8d4bfa7053 Fix transient NO_SWITCHER / CDP race in box-chat-cdp.py
Three fixes for flaky main-chat reads (pip/opm):
1. ENSURE: retry chat-switcher lookup 4x with 2s waits instead of
   immediate NO_SWITCHER (React may still be rendering).
2. ev(): drain CDP events until matching command id arrives;
   previously the first recv() could grab a browser event instead
   of our evaluate response, returning None.
3. main(): reconnect fresh websocket on each retry (3 attempts);
   reusing a stale ws after page navigation gave dead JS contexts.

Verified: 7/8 reads succeed across all 4 agents; the 1 failure
was THREAD_NOT_FOUND while opm was actively in a side chat,
self-healed on next attempt.

Session: sidechat/chromebox-ops
2026-10-04 19:02:17 +00:00
operator-main 0822960810 Add main-loop enable/disable per-agent toggle
- self_main_loop.py: 'enabled' map in config (default all True);
  do_check skips disabled agents (marks disabled:true in results);
  new enable/disable actions with optional --agent.
- box-ctl.py: main-loop enable|disable [--agent <name>] actions,
  USAGE updated.

Check skips disabled agents so the loop can be toggled per
Chromebox without stopping the systemd timer.

Session: sidechat/chromebox-ops
2026-10-04 18:52:54 +00:00
operator-main e93e9b6122 Add self_main_loop.py main-chat self-monitor + box main-loop action
Reads each fleet agent's muse.ai Main chat on a 5-min systemd timer
(self-main-loop.timer). On new messages since the per-agent watermark,
posts a concise digest to that agent's prompting sidechat (dm.py, opm
as neutral sender - mirrors box notify), prompting the operator to
check main chat via DM/box. Escapes the main-chat-goes-unread failure
mode. No backfill on first run; silent when nothing new; read/send
failures logged without killing the timer; flock overlap guard.

box-ctl.py: main-loop check | status (fleet section).

Session: sidechat/chromebox-ops
2026-10-04 18:39:46 +00:00
operator-main f679ced960 Add identity-audit-check.sh and box identity-audit action
identity-audit-check.sh: proper script replacing the identity-audit-watch
cron inline SSH one-liner. Reads a bl-local cache of the VM audit JSON
(bl cannot SSH to VM; VM hourly audit should push to var/identity-audit.json).
Exits 0 clean, 1 on drift, 2 if cache missing.

box-ctl.py: new identity-audit action returning drift as JSON.
2026-10-04 18:35:57 +00:00
operator-main a76a776a87 Add cdp-latency-check.sh and box cdp-latency action
Proper script replacing the inline-SSH latency monitor. Probes each relay /json/version via pinned ports from netvm-names.sh, outputs name:latency_ms:code per node. box-ctl.py cdp-latency runs it and returns JSON.
2026-10-04 18:34:52 +00:00
operator-main 882dfd8254 Add watchdog-alert-check.sh (box watchdog-alerts helper script)
Self-contained FAILED-relaunch scanner for chromebox-watchdog.log
with watermark at NETVM_ROOT/watchdog-alert-watermark.txt.
Exits 0 quiet when clean, 1 with new lines printed when alerting.
The box-ctl.py watchdog-alerts action (in 2db0d92) drives this script.

Session: sidechat/chromebox-ops
2026-10-04 18:34:33 +00:00
operator-main 2db0d92d5a Add chrome-error-scan.sh and box chrome-errors action
Self-contained per-profile chrome log scanner with watermark-based
new-match detection. Box CLI action returns JSON per-profile counts.

Session: sidechat/chromebox-ops
2026-10-04 18:34:09 +00:00
operator-main 31ed4e2f99 Add relay-health-check.sh and box relay-health action
Converts the cdp-relay-health-monitor from inline SSH (nested quoting
bugs) to a proper self-contained script on bl. Uses pinned ports from
netvm-names.sh as single source of truth.

New files/actions:
- bin/relay-health-check.sh: checks all four CDP relays, exits 0/1
- box-ctl.py relay-health: JSON wrapper for the Box CLI

Session: sidechat/chromebox-ops
2026-10-04 18:32:44 +00:00
operator-main 550e30901b fix: placement verification and sidechat policy enforcement
- dm.py: placement-aware verify (verify_placement), checked_uuid logging, placement_mismatch events
- main-chat-watchdog.py: P0 alerts on placement_mismatch
- box-ctl.py: notify routes to sidechat, box policy command
- jobs: ops-audit and pipe-demo use sidechats
- response-harvester.py: chain deduplication

Session: sidechat/ops-restore
2026-10-04 18:29:13 +00:00
operator-main ae1bf17de5 Fix relay watchdog false-positive: sudo the pkill
restart_relay() ran pkill without sudo, but relay processes are
root-owned and the timer runs as User=super. The kill failed EPERM
(silently swallowed by || true), the old relay kept running, and
SO_REUSEADDR let the replacement double-bind the same port. The
post-restart health check then passed and logged "restarted OK"
when nothing was actually restarted.

Adding sudo -n to the pkill, matching the sudo -n ip netns exec
already used to start the relay.

Session: sidechat/chromebox-ops
2026-10-04 18:22:10 +00:00
operator-main c07802dfa2 Fix watchdog relaunch-loop: guard before relaunch, main-process PID filter
The relaunch-loop guard only protected the kill step, not the relaunch.
When CDP was unreachable on a slow-starting browser, the watchdog would
invoke netvm-chrome.sh (which kills the existing browser) before checking
if it was recently launched — piling up 5 chromiums on opm.

Now the <120s check runs before the relaunch and skips the entire cycle.
Also fixed the PID check to match only the main browser process
(--remote-debugging-port, excluding --type= renderer/gpu children).

Session: sidechat/chromebox-ops
2026-10-04 18:21:55 +00:00
operator-main 8d5d5c0f3b Unify CDP relay ports: pin registry ports in netvm-names.sh
netvm-node-up.sh was starting the CDP relay with the hash-derived
CDP_PORT while cdp-relay-watchdog.sh pinned muse->9410, pip->9420,
646->9430, opm->9440. Since netvm-chrome.sh calls netvm-node-up.sh
on every browser relaunch, each restart spawned a wrong-port zombie
relay (9353, 10355, 10239...).

The pinning now lives in netvm_names() itself, making it the single
source of truth for all consumers (node-up, chrome, cdp, accounts,
watchdog). CDP_PORT_OVERRIDE still takes precedence for future nodes.

Session: sidechat/chromebox-ops
2026-10-04 18:21:47 +00:00
cred-driver 7b5271a69a muse-signin: mask secrets in progress output at the source
Identifier, OTP code, and account-name values replaced with [redacted] in all progress prints. Line structure and markers preserved (APPROVAL_NEEDED/NEEDS_HUMAN/SUCCESS prefixes intact); exit codes 0/2/3/4 unchanged, no consumer parses stdout. Defense in depth: onboard-driver already scrubs its passthrough; this covers manual operator flows too.
2026-10-04 18:07:48 +00:00
cred-driver 86da8b5539 onboard-driver: scrub secrets from signin output passthrough
- Redact identifier/code (>=4 chars) from muse-signin.py stdout/stderr before passthrough (it echoes OTP input).

- Catch TimeoutExpired: its str() includes argv with --email/--otp; print generic timeout instead.

- Log email_masked instead of raw email to job-log.jsonl (rc=4 branch).
2026-10-04 17:48:54 +00:00
op-thread-uuid ae4f2640ad dm: emit thread_uuid on the SENT and VERIFIED line
dm_send already knows the thread UUID at send time (alias resolution, nav URL capture, autoprovision capture) but dropped it: the only stdout channel the board parses carried no thread info, so every auto-logged DM row had thread_uuid null.

Now prints '... SENT and VERIFIED thread=<uuid>' when known, unchanged line otherwise (main-chat sends, UUID-capture failures stay honestly null -- never fabricated). Backward compatible: board _BOX_DM_SENT_RE has no end anchor; bl consumers (job-dispatch.py, siphon-bl.py) use substring matching.

Worktree note: unrelated uncommitted changes remain (job_id followup-correlation hunks in this file, followup-sweeper.py, response-harvester.py, untracked helpers) -- not mine, not staged.

Session: sidechat/box-dms-ui
2026-10-04 17:44:33 +00:00
operator 33a0f295b6 feat(pipeline): register 3-stage ops-audit pipeline definitions and wire super-cli prune command 2026-10-04 17:23:28 +00:00
operator 2b19d2cb45 feat(pipeline): add stop and prune commands to pipeline engine and CLI
- Add stop_pipeline and prune_pipelines to bin/pipeline_engine.py
- Support prefix matching and custom cancellation reason
- Wire 'super pipeline stop <run_id>' and 'super pipeline prune [--max-age H]' into bin/super-cli.py
2026-10-04 16:58:15 +00:00
operator 6cafdfabef feat(pipeline): add multi-agent pipeline engine, sidechat auto-provisioning, and CDP event isolation
- Add bin/pipeline_engine.py for persistent multi-agent execution tracking in pipelines.json
- Add jobs/pipe-demo-step1.json and jobs/pipe-demo-step2.json demo pipeline definitions
- Use ev1 in bin/muse-chat-api.py across send/messages/compose/create to avoid dropping return values on CDP event chatter
- Support Muse unconfirmed signup error handling in bin/muse-signin.py
- Add runtime state and telemetry files to .gitignore
- Track dynamic pipe sidechat mappings in job-sidechats.json
2026-10-04 16:56:15 +00:00
operator 1d739f6b6a feat(loop): codify external intrinsic loop management, progressive remediation, and operational runbook
- Add bin/gravity.py loop diagnostics, reconstruction, and progressive remediation
- Wire hard-break alerting to job-log audit and operator direct message
- Add comprehensive architecture and operational specification in docs/LOOP-MANAGEMENT.md
- Add sidechat thread auto-provisioning fallback on 'Navigated to: None' in bin/dm.py
- Support Muse unconfirmed signup error handling in bin/muse-signin.py
- Track dynamic pipe sidechat mappings in job-sidechats.json
2026-10-04 16:52:54 +00:00
operator-main b8f02af572 docs: add Box Web Surface and orchestration architecture guide 2026-10-04 16:50:57 +00:00
operator-main 5b3d77fb60 feat(tests): add comprehensive unit test suite for variables, strategy modulation, and loop health 2026-10-04 16:50:13 +00:00
operator-main a2c5832aff fix(web): pass type field in strat modal payload to match VM API schema 2026-10-04 16:48:38 +00:00
operator 5063fcb469 fix(cdp_queue): auto-purge stale queue tickets older than 2x acquire timeout 2026-10-04 16:47:36 +00:00
operator 2fa2955fb3 feat(harvester): add opportunistic harvest_main_feed with zero navigation and per-node fault isolation 2026-10-04 16:45:34 +00:00
operator 8bfe94d0f3 test(nav): add unit test suite for main chat policy, sidechat routing, and transfer lifecycle 2026-10-04 16:43:50 +00:00
operator-main a383d83c3c chore(jobs): track active sidechat mapping for job dispatchers 2026-10-04 16:39:44 +00:00
operator-main cf8f59b737 fix(watchdog): generalize CDP page health check for Muse targets 2026-10-04 16:39:30 +00:00
operator 87fd93e7a6 feat(dm): implement Reset-at-Begin and Leave-in-Sidechat pattern to preserve Main Chat DOM 2026-10-04 16:39:23 +00:00
operator-main 5593090cd6 feat(web): add box.css stylesheet for Box web console 2026-10-04 16:37:53 +00:00
operator aa125bb7be feat(onboarding): propagate NEEDS_SIGNUP (code 4) through onboard-driver and muse-signin 2026-10-04 16:37:26 +00:00