MF Automations · Backlog

queue · working · finished — from devops/BACKLOG.md
39 items updated Jun 30, 2:45 AM ET
0 agents working 25 draft PRs 0 agent-queued cct: okchinery: okmaui: ok

Queue

10

Deferred-but-tracked. Not started — sorted by priority.

ARCH-2P12026-06-15

Decompose ada-api/server.js (~2.2k lines)

details
Decompose ada-api/server.js (~2.2k lines). One process hosts SIX revenue product apps (deepdive/listwise/divorcepro/bundle/moveart/movemusic via makeApp()) + Stripe checkout & order fulfillment + LLM report generation + email/follow-up scheduler + input sanitization + webhook idempotency + per-product ranking. Any edit risks cross-product breakage; payment/fulfillment is tangled with per-product report gen. Split into per-product modules + shared payment/email/llm libs. Also the site of PERF-1..4 (sync I/O).
Why deferred Highest external blast radius (six paid endpoints + Stripe); needs its own plan.
Source vultr/relay/ada-api/server.js; cross-ref PERF-1..4.
ARCH-3P12026-06-15

Decompose research_ingestion.py (~3.7k lines — largest file in the audit)

details
Decompose research_ingestion.py (~3.7k lines — largest file in the audit). Comments show it was assembled by merging three services. Merges ≥4 subsystems: doc ingest (L2169-2502), embedding across backends (L230-318), pgvector backend incl. SQL search (L853-1324), hybrid BM25+vector search engine (L2648-3212), GDPR forget/redact w/ HMAC (L1704-2087), streaming/sessions (L3213-3559), multimodal (L3560-3701) — plus two storage backends (Chroma+pgvector). Split into ingest / search / forget-compliance / streaming modules + shared embedding+storage libs. Also site of ASYNC-4.
Why deferred Core RAG service; high blast radius. Own project.
Source frank/orchestrator/services/research_ingestion.py; cross-ref ASYNC-4.
ARCH-7P12026-06-15

Decompose frank-service-health-monitor/server.js (~1.5k lines)

details
Decompose frank-service-health-monitor/server.js (~1.5k lines). Three originally-separate subsystems accreted: passive health polling+ntfy alerting (L206-531), an alert correlator w/ embedded YAML rule parser + SQLite claim store (L653-953), and an auto-quarantine actuator that can launchctl bootout services and block deploys (L955-1257). The destructive quarantine actuator should not share a file with passive polling. Split monitor / correlator / quarantine.
Why deferred Quarantine actuator has real destructive power; isolating it reduces risk.
Source frank/orchestrator/services/frank-service-health-monitor/server.js.
ASYNC-3P12026-06-15

frank_stems_service.py:74/100/166: subprocess.run(timeout=600) + requests.post on the event loop

details
frank_stems_service.py:74/100/166: subprocess.run(timeout=600) + requests.post on the event loop. Async separation handler runs a CPU-bound up-to-600s subprocess plus blocking Drive uploads inline. Fix: run_in_executor for the subprocess + async client for the posts.
Why deferred A single separation can freeze the loop for minutes.
Source frank/orchestrator/services/frank_stems_service.py:74,100,166.
DB-1P12026-06-15

jre-orchestrator/dashboard.py:347: N+1-in-SQL on the financials path

details
jre-orchestrator/dashboard.py:347: N+1-in-SQL on the financials path. Two correlated SELECT SUM(amount) FROM payments WHERE job_id = j.id … subqueries per job row → 2N per-row subqueries for N completed jobs (unbounded for period='all'); rows then filtered in Python. Fix: single LEFT JOIN payments + GROUP BY j.id with SUM(...) FILTER (WHERE type=…).
Why deferred 2N payment subqueries per request; latency ∝ job volume.
Source vultr/relay/jre-orchestrator/routers/dashboard.py:347.
DUP-2P12026-06-15

Security-relevant drift: two bridge-hmac.js impls

details
Security-relevant drift: two bridge-hmac.js impls. …/scripts/lib/bridge-hmac.js (49 lines) caches the HMAC key with a 1h TTL and re-fetches via frank-secret on expiry (hardened 2026-05-02 for ~90-day rotation); …/scripts/orchestrator/lib/bridge-hmac.js (35 lines) caches forever (if (_bridgeHmacKey) return). After a key rotation, orchestrator-signed requests use a stale key until process restart. Same divergent pair under maui/frontend/scripts/. Fix: unify to the TTL-aware version.
Why deferred Auth/bridge-signing correctness after key rotation — higher priority than the other dups.
Source frank/scripts/lib/bridge-hmac.js vs frank/scripts/orchestrator/lib/bridge-hmac.js.
ARCH-1P22026-06-13

Decompose the frank-ops-chat-handler-v2 god-file (~11k lines)

details
Decompose the frank-ops-chat-handler-v2 god-file (~11k lines). One index.js carries voice assist / call lifecycle, verification, recall/forget/inbound/assemble/summary probes, admin send, onboarding orchestration, divergence, delivery-status, task-close, pipeline admin — 6–8 distinct responsibilities. Siblings are ~500–1700 lines. Untestable at the handler level because of its size (it's why ops-chat is excluded from the supertest handler-test task). Split into focused modules with exported, testable units. Overlaps the §6.5 monolith-decomposition arc.
Why deferred The brain — highest-risk service to touch; needs its own project + plan, not a drive-by. Filed so it isn't lost.
Source frank/orchestrator/services/frank-ops-chat-handler-v2/index.js; §6.5 runbook.
ARCH-8P22026-06-15

Decompose registry-sync.js (~1.7k lines)

details
Decompose registry-sync.js (~1.7k lines). Service-registry sync daemon bundling auto-discovery (PM2/MCP/plugins), a 10-step propagation chain incl. remote SSH writes to the Maui host + RAG ingest (L281-501), deregistration cleanup, markdown table editing, PM2 config gen, drift detection, weekly audit, HTTP control server. Cohesive around one domain but long; split propagate/deregister chains + discovery/builders into modules.
Why deferred Lower blast radius than the P1 services; cohesive.
Source frank/orchestrator/src/services/new-services/registry-sync.js.
ARCH-9P22026-06-15

Decompose knowledge_router.py (~2.4k lines)

details
Decompose knowledge_router.py (~2.4k lines). Core knowledge-router RAG service holding 5 backend impls (Chroma/Hybrid/Qdrant/FileCorpus/SessionTranscript), 3 embedding strategies, semantic ranking, query routing, LRU+TTL cache, HyDE augmentation, and FastAPI routes in one module. Each backend/strategy is independently substitutable → split backends/ embeddings/ ranking/ api to allow isolated testing.
Why deferred Cohesive around querying; lower blast radius than the messaging/billing P1s.
Source frank/orchestrator/services/knowledge_router.py.
PERF-4P32026-06-15

Three pollers recompile constant regexes inside hot loops

details
Three pollers recompile constant regexes inside hot loops. frank-api-quota-monitor/server.js:198 (new RegExp per log line in extractTsMs), frank-stylometric.js:203 (HEDGE/INTENSIFIER/PROFANITY rebuilt per call + N full-text passes), subscription-poller.js:179/201 (~5 tag regexes compiled per feed item). All patterns are constant → precompile once. Fix: hoist regex compilation out of the loops/per-call.
Why deferred Wasted compilation ∝ lines/items scanned, but on setInterval pollers not request paths → bounded.
Source …/frank-api-quota-monitor/server.js:198; …/frank-stylometric.js:203; …/subscription-poller.js:179,201.

Working

27

In progress — overflow agents + open draft PRs.

PIPE-3P12026-06-17

Commit a clean, REAL prod desired-state (the thing a PR edits + migrate.js diffs)

details
Commit a clean, REAL prod desired-state (the thing a PR edits + migrate.js diffs). Today only the *synthetic* fixtures/dump.skeleton.json (4-5 apps) exists — there is no committed real ~260-app desired state, so "the PR is the change" can't work yet. Produce a names-only desired-state skeleton carrying only service-specific env keys (strip inherited shell env — HOME/PATH/USER — or migrate shows noise), fix the stale ports.canonical.json (ops-chat script = …/frank-ops-chat-handler-v2/index.js but the live exec is …/scripts/mfa-launchers/frank-ops-chat-handler-v3.sh — settle which is authoritative; Frank is reachable now), and extend ports.canonical.json to every service to be gated. Critical-path blocker for prod reconcile.
Why deferred Phase-C foundation; read-only against Frank, safe to do now.
Source RECONCILE-vs-REBUILD.md; ports.canonical.json; CI-STATUS.md (v2/v3 note).
PIPE-4P12026-06-17

Implement the Phase-4 apply write-path

details
Implement the Phase-4 apply write-path. promote.js apply / migrate.js --apply throw by design today. Per the doctrine: validated dump.pm2 backup on Frank first; TOCTOU recheck (dump sha256+mtime unchanged preview→apply, ABORT on drift); per-app branching (ADDED→pm2 start --only; CHANGED→env-only restart --update-env vs structural delete+start; REMOVED→never auto-stop, human gate); data-bearing never-touch allowlist; launch gated apps through port-gate.sh; per-app rollback (never fleet resurrect); --i-have-reviewed + induced-restart validation window. Biggest remaining chunk — the actual prod-write unlock. Depends on PIPE-3 + the interpreter fix (PR #16).
Why deferred Deliberately gated; no Frank-write path exists until this is built + reviewed.
Source CICD-ROADMAP.md Phase C Gate 1; RECONCILE-vs-REBUILD.md (danger cases); promote.js/migrate.js.
ARCH-4P12026-06-15

Decompose realestateai/orchestrator_endpoint_v2.py (~1.9k lines)

details
Decompose realestateai/orchestrator_endpoint_v2.py (~1.9k lines). Live voice-AI orchestrator: intent NLU (IntentDetector L147-336), param extraction (ParameterExtractor L337-483), response formatting (ResponseFormatter L484-547), 1000-line Orchestrator mixing routing/API-dispatch/business logic (L548-1567), FastAPI app, inbound-call webhook w/ its own sqlite caller DB (L1594-1893). Each class already has a clean boundary → split into intent/extract/format/orchestrate/webhook modules. Also site of ASYNC-2.
Why deferred Live customer voice product.
Source vultr/relay/realestateai/app/orchestrator_endpoint_v2.py; cross-ref ASYNC-2.
ARCH-5P12026-06-15

Decompose frank-channel-normalizer/index.js (~1.5k lines)

details
Decompose frank-channel-normalizer/index.js (~1.5k lines). Central inbound-message normalizer mixing transport (5 providers: SMS/Twilio, WhatsApp, Telnyx, iMessage/BlueBubbles, email), 3 sig-verify schemes (L446-540), attachment hydration, identity auto-link (L604-982), human-approval workflow (L983-1110), v2 forwarding+retry, pgvector ingest, Redis consumers. A change to one channel risks all. Split per-channel adapters + shared identity/approval/storage core. PIPE-2 (sig-gating) lives in this file.
Why deferred Every customer channel flows through it.
Source frank/orchestrator/services/frank-channel-normalizer/index.js; cross-ref PIPE-2.
ARCH-6P12026-06-15

Decompose frank-mfa-billing/index.js (~1.7k lines)

details
Decompose frank-mfa-billing/index.js (~1.7k lines). Three distinct business domains in one process: Stripe subscription-lifecycle webhooks (L395-898), Telnyx SMS verification (L928-1008), usage metering + threshold warnings (L1009-1198), customer provisioning side-effects (Drive sharing, imsg registry, person-entity), dashboard HTML rendering, checkout endpoints. Payment-critical code shares a process with SMS + dashboard. Split into billing-webhooks / sms-verify / metering / provisioning.
Why deferred Payment-critical; should be independently deployable/testable.
Source frank/orchestrator/services/frank-mfa-billing/index.js.
PERF-1P12026-06-15

ada-api/server.js:169 logSubmission rewrites an unbounded JSON array per request

details
ada-api/server.js:169 logSubmission rewrites an unbounded JSON array per request. Every submission does blocking readFileSync(whole product log)→JSON.parse→push→writeFileSync(whole array), called from ~20 POST handlers. Cost grows O(n) with accumulated submissions and blocks the event loop for all concurrent requests. Fix: append-only NDJSON (fs.appendFile) or move to the DB already backing db_id; at minimum make it async.
Why deferred Per-submission latency + event-loop block scale linearly with history.
Source vultr/relay/ada-api/server.js:169 (callers 774/1086/1538/1870…).
ASYNC-1P12026-06-15

realestateai/app/main.py:340 (+410/466/520/624): blocking requests.get on the event loop

details
realestateai/app/main.py:340 (+410/466/520/624): blocking requests.get on the event loop. Async FastAPI routes call the synchronous property_serviceUSRealEstateAPIClient._make_requestrequests.get (us_real_estate_client.py:128) with no await/executor. Fix: httpx.AsyncClient (or run_in_executor).
Why deferred Sync HTTP w/ network timeout runs directly on the loop → stalls all concurrent requests.
Source vultr/relay/realestateai/app/main.py:340; us_real_estate_client.py:128.
ASYNC-2P12026-06-15

realestateai/orchestrator_endpoint_v2.py:659: blocking requests-client on the event loop

details
realestateai/orchestrator_endpoint_v2.py:659: blocking requests-client on the event loop. Async orchestrator handler invokes the synchronous USRealEstateAPIClient; the file's httpx import (L24) is dead — the real call path is blocking. Fix: use the async httpx client that's already imported.
Why deferred Same loop-stall as ASYNC-1 on the v2 path.
Source vultr/relay/realestateai/app/orchestrator_endpoint_v2.py:659.
ASYNC-4P12026-06-15

research_ingestion.py:638: urllib.urlopen(timeout=60) on the event loop

details
research_ingestion.py:638: urllib.urlopen(timeout=60) on the event loop. Three async routes (≈3098/3576/3652) call sync _call_gemini_embed, which blocks on urllib for every multimodal request. Fix: httpx.AsyncClient. In the ARCH-3 god-file.
Why deferred Embed HTTP blocks the loop per multimodal request.
Source frank/orchestrator/services/research_ingestion.py:638; cross-ref ARCH-3.
SEC-1P22026-06-13

Rotate + scrub previously-leaked credentials in pushed repos

details
Rotate + scrub previously-leaked credentials in pushed repos (Plaid PROD key, Maui GW_TOKEN, ORCHESTRATOR_API_KEY, gho_ PATs). Rotate at source; history-purge or delete/recreate the standalone dup repos. ⚠️ Severity disputed: REPO-STATE-REVIEW-2026-06-13.md rates this P0/rotate-today; filed P2 here per Sean's finish-Maui-first call. [2026-06-17 update] gho_ PATs DONE — verified revoked/dead + remotes de-leaked: ~/orchestrator & ~/scripts carry 0 embedded tokens, ~/on-the-list's embedded token returned HTTP 401 (dead) and the string was removed. webhooks.py:697 GW_TOKEN literal scrubbed (PR #17 → os.getenv). Remaining 3 PRODUCTION rotations HELD per Patrick (2026-06-17): Plaid prod secret, Maui GW_TOKEN, ORCHESTRATOR_API_KEY — not rotated.
Why deferred Repos private → exposure bounded. Plaid is dashboard-only (no rotation API). GW_TOKEN feeds live revenue-bearing iMessage alerts (Vultr/Maui) → rotation must be coordinated across gateway + all consumers; a miss breaks prod. Revisit post-burn-in. Storage posture going forward: secret-vault + frank-secret.
Source REPO-STATE-REVIEW-2026-06-13.md §P0 · SECURITY-rotate-tokens.md. Rotation runbook per cred: Plaid dashboard → Keys → rotate, then update frank-secret plaid-production-secret + the n8n Plaid workflows; GW_TOKEN → new token, update gateway + frank-secret maui-gateway-token/frank-gateway-token + every consumer (webhooks.py env, gmail-monitor.sh env); ORCHESTRATOR_API_KEY → new UUID, update frank-secret orchestrator-api-key + ecosystem.frank.config.js + consumers.
SEC-2P22026-06-13

Close the gitleaks detection gaps

details
Close the gitleaks detection gaps. CI scans working-tree NEW leaks only, so import-time leaks slip through. [2026-06-17] webhooks.py:697 portion CLOSED — the GW_TOKEN Bearer literal was scrubbed to os.getenv('GW_TOKEN','') (PR #17), so the undetected in-tree literal is gone. Remaining: n8n jsCode blobs and embedded audit-report JSON are still not scanned by the gitleaks gate (it only catches NEW working-tree leaks of known formats).
Why deferred Same as SEC-1 — bounded; bundle into the security circle-back.
Source REPO-STATE-REVIEW-2026-06-13.md (CI gate analysis); .github/workflows/ci.yml (--no-git, new-leaks-only).
PIPE-2P22026-06-13

Gate the provider-sig (Twilio/Telnyx) REQUIRE_INBOUND_SIG default

details
Gate the provider-sig (Twilio/Telnyx) REQUIRE_INBOUND_SIG default. Distinct from PIPE-1 (now done): the iMessage verifyMauiHmac boundary is gated, but the SMS/WhatsApp adapters still accept an absent signature unless REQUIRE_INBOUND_SIG=true (default false) — a *different*, more durable hole (stays loose even once a token exists, until explicitly flipped). No gate exercises it. Add a test, then flip the default before real SMS traffic.
Why deferred No real SMS/WhatsApp customers today → not yet load-bearing. Slot into test-hardening alongside the eventual REQUIRE_INBOUND_SIG=true flip.
Source frank/orchestrator/services/frank-channel-normalizer/index.js:498,499,529,530; TESTING.md finding #3.
REPO-1P22026-06-13

Resolve the consolidate-vs-fragment strategy with Patrick, then archive duplicate standalone org repos

details
Resolve the consolidate-vs-fragment strategy with Patrick, then archive duplicate standalone org repos. maui-platform is the source of truth (AGENTS.md:7); mfautomations/{scripts,orchestrator,operator-kernel,…} + the migration-staging Frank folders are duplicates that re-fragment the monorepo. Extract only the genuinely-new client/side projects from migration-staging, then delete the bundle.
Why deferred Not blocking the Maui build; needs a cross-operator decision, not just code.
Source REPO-STATE-REVIEW-2026-06-13.md §Conflict surface.
DOC-1P22026-06-13

Update secret-vault/README.md status line

details
Update secret-vault/README.md status line — says "Implementation pending" but v0.1.0 MVP is built + tested (11 test files, tagged). Stale.
Why deferred Trivial, different repo.
Source secret-vault/README.md Status section vs git log (v0.1.0 merge 9983f7c).
PIPE-5P22026-06-17

Decide + wire WHERE apply executes

details
Decide + wire WHERE apply executes (on-Frank locally vs SSH-from-Cosmo over the mesh). The toolkit was built on Cosmo to read Frank read-only; the reconcile *writes* to Frank. Settle the execution model + safe-SSH idiom; databases stay out of scope.
Why deferred Settles with PIPE-4.
Source START-HERE.md (safe SSH idiom); ADR/0001 (Frank = prod box).
PIPE-6P22026-06-17

Decide the prod branch model + promote DevBranch→main

details
Decide the prod branch model + promote DevBranch→main. main is the prod desired-state and is currently behind DevBranch; settle which branch reconciles to Frank (master vs release) and the DevBranch→main promotion rule.
Why deferred Decision, not just code; pairs with PIPE-3/4.
Source CICD-ROADMAP.md Phase C ("decide prod branch model"); BRANCHING.md.
PIPE-7P22026-06-17

Resolve branch protection so REQUIRED checks BLOCK a merge

details
Resolve branch protection so REQUIRED checks BLOCK a merge. Today CI reports red/green but does not block (403 on the private plan) — the gate is human discipline. Upgrade the plan, or go public *after* a git-history secret scrub.
Why deferred Fine for now (you are the gate); needed before an automated prod path.
Source CICD-ROADMAP.md §2 + Phase D.
PIPE-8P22026-06-17

B2 full-chain E2E

details
B2 full-chain E2E (inbound→normalizer→ops-chat→reply) — the real "did the product still work" gate before prod changes. Blocked on the monolith 127.0.0.1-bind decomposition (every cross-service hop ECONNREFUSEs under bridge net). B1 single-hop is done.
Why deferred Needs the monolith decoupled.
Source CICD-ROADMAP.md Phase B (B2); DEV-ENV-BRINGUP.md §6.5; TESTING.md.
GH-1P22026-06-13

Sync this BACKLOG → GitHub Issues

details
Sync this BACKLOG → GitHub Issues. Want backlog rows tracked as real GitHub issues (a script or CI job that creates/updates issues from the table, or a one-time port then issues-as-source-of-truth). Decide direction (backlog→issues one-way, or issues canonical) first.
Why deferred Process improvement, not blocking the build. Needs the GitHub-plan/permissions question (GH-2) resolved alongside.
Source This file; relates to GH-2.
GH-2P22026-06-13

Harden the GitHub repo + evaluate the tooling surface

details
Harden the GitHub repo + evaluate the tooling surface. Branch protection (currently 403 on private repo — user is the merge gate), required status checks, CODEOWNERS enforcement, Copilot PR review, Dependabot/security scanning, and research into best-practice setup for a private monorepo. Produce a recommended config + plan decision (Team/Pro vs current).
Why deferred Needs a plan/cost decision (GitHub tier) and research; not blocking the build.
Source maui-cicd-devbranch notes (branch-protection 403); REPO-STATE-REVIEW-2026-06-13.md §Pipeline.
PERF-2P22026-06-15

ada-api/server.js report-status polls do a full sync directory scan

details
ada-api/server.js report-status polls do a full sync directory scan. Three product status-poll GET handlers (listwise :1263, moveart :1610, movemusic :1942) readdirSync + per-file readFileSync/JSON.parse looking for a customer_email match; an unknown/no-match email (or still-generating report) reads+parses EVERY *-delivery.json synchronously. Clients poll every few seconds → repeated O(files) event-loop blocks. Fix: index by email/session_id or resolve the deterministic filename; use async fs + cache.
Why deferred Status-poll cost is O(delivery-file count) per poll, all sync; degrades as reports dir grows.
Source vultr/relay/ada-api/server.js:1263,1610,1942.
PERF-3P22026-06-15

frank-synthflow-actions/index.js:202 re-reads + linear-scans contacts.json per inbound call

details
frank-synthflow-actions/index.js:202 re-reads + linear-scans contacts.json per inbound call. On the unknown-caller fallback (client360 miss), loadCallerContext does readFileSync+JSON.parse of contacts.json on every call, then a per-entry normalizePhone regex scan. No caching; called from live Synthflow webhooks (474/887/959). Fix: load+cache at startup (mtime-invalidate) and build a normalized-phone→contact map for O(1) lookup.
Why deferred Every cache-miss inbound call pays a sync disk read + O(contacts) scan in the live voice path.
Source frank/orchestrator/services/frank-synthflow-actions/index.js:202-245.
ASYNC-5P22026-06-15

self_improving_distiller.py:226: blocking requests.post loop + sync generate_content in async poll_loop

details
self_improving_distiller.py:226: blocking requests.post loop + sync generate_content in async poll_loop. Background async task (created L307) does a Gemini call per transcript + per-finding ingestion posts inline. Fix: run_in_executor / async client.
Why deferred Background task, not a request path → lower priority, but still blocks the shared loop.
Source frank/orchestrator/services/self_improving_distiller.py:226,265.
DB-2P22026-06-15

jre-orchestrator/dashboard.py:32 + callers.py:93: many sequential aggregate round-trips per request

details
jre-orchestrator/dashboard.py:32 + callers.py:93: many sequential aggregate round-trips per request. get_kpis fires ~25 independent COUNT/SUM/AVG queries serially (jobs COUNT-scanned ~12×); callers segments fire 8 sequential COUNTs. Fix: collapse each to single-pass conditional aggregation (COUNT(*) FILTER (WHERE …)).
Why deferred ~25 (+8) sequential round-trips + repeated full scans per dashboard load.
Source vultr/relay/jre-orchestrator/routers/dashboard.py:32; routers/callers.py:93.
DEAD-1P22026-06-15

Remove ~19.5k lines of tracked backup/scratch cruft

details
Remove ~19.5k lines of tracked backup/scratch cruft. git ls-files | grep -iE '\.bak|/_bak/|-bak-|\.task…-work/|\.disabled$' → 9 tracked files, 19,571 lines. Worst: ops-chat-handler.sh.bak2-20260507-… duplicated in BOTH frank/scripts/ and maui/frontend/scripts/ at 7,053 lines each (14,106 lines = 72% of total); .task120-work/server.js dup'd in both trees (1,144 ea); _bak/learn-then-execute-…/ (4 files, ~3,126); tts-speak-response.sh.disabled. Safe git rm (timestamped backups / .disabled).
Why deferred No runtime impact, but pollutes grep/search, bloats clones, risks editing the wrong copy.
Source git ls-files cruft scan (2026-06-15).
DUP-1P22026-06-15

73 byte-identical lib files copy-pasted between frank/scripts/lib/ and maui/frontend/scripts/lib/

details
73 byte-identical lib files copy-pasted between frank/scripts/lib/ and maui/frontend/scripts/lib/. Per-file md5 over 80 shared basenames: 73 identical, 7 already diverged (contacts.js, send-message.js, send-message-internal.js, contact-memory-append.sh, degraded-queue.sh, failure-detector.sh, maui-state.sh). Every fix must be applied twice; the 7 divergences prove drift is active. Fix: consolidate to one shared lib (package/symlink), reconcile the 7.
Why deferred Double-maintenance + active drift across two trees.
Source frank/scripts/lib/maui/frontend/scripts/lib/.
DUP-3P22026-06-15

Two forked imsg-rpc-bridge.js (1259 vs 1074 lines, 239 changed lines ≈19%)

details
Two forked imsg-rpc-bridge.js (1259 vs 1074 lines, 239 changed lines ≈19%). maui/frontend/scripts/imsg-rpc-bridge.js vs …/scripts/orchestrator/imsg-rpc-bridge.js — a substantial fork, not a stale copy; unclear which is canonical. Also orchestrator/lib/{complex-dispatch.js,simple-responder.js} are md5-diverged between the frank and maui trees. Fix: pick canonical, reconcile, dedupe (alongside DUP-1).
Why deferred Two 1000+ line RPC bridges can route messages differently; behavior depends on which executes.
Source maui/frontend/scripts/imsg-rpc-bridge.js vs …/orchestrator/imsg-rpc-bridge.js.

Finished

2

Completed & verified, merged to Done.

OVERFLOW-1P0now

Claude-token overflow dispatcher — parallel CCT→Chinery→Maui, clearing this backlog

Parallel multi-account OAuth dispatcher: saturates every healthy Claude account at once and overflows CCT→Chinery→Maui as each hits its window cap, opening a draft PR per backlog item. Live: 0 agents working · 25 draft PRs · 0 agent-queued · 26 done. Scripts on Frank: overflow-{dispatch,worker,headroom,seed}.sh (PM2 frank-overflow-dispatch).
PIPE-12026-06-13

HMAC enforcement gate added

HMAC enforcement gate added (devops/test/b1-hmac-enforcement.sh, run-all.sh --hmac, wired into deploy.sh). Closes the false-assurance gap: the --b1 injection gate only ever signs correctly, so it never proved *rejection*. The new gate asserts the verifyMauiHmac boundary on the keyed MIRROR stack — valid→200, forged→401 hmac_sig_mismatch, missing→401 hmac_missing_signatureverified live on the box (falsification-checked: it does go red when an assertion is wrong). Scope correction vs the original ticket text: PIPE-1 bundled three things; only the iMessage verifyMauiHmac boundary is closed. The no-key fail-open was *deliberately not* gated (it's a dev affordance; gating it would fail the deploy when enforcement is correctly enabled — the gate skips loudly on an unkeyed stack instead). The provider-adapter REQUIRE_INBOUND_SIG default is a different path (verifyTwilioSig/Telnyx, not verifyMauiHmac) and is split out as PIPE-2. Drive-by: fixed an -x-f guard in run-all.sh that had silently demoted --b1 to LIST on the box (exec bit doesn't survive rsync).