143 lines · 11.5 KB · Markdown
RawDownload

Professionalize Loop — Mission Ledger

Started: 2026-07-12 18:05 EDT · Deadline: 2026-07-13 06:05 EDT (12h) Branch: loop/professionalize (off origin/main @ 41a0bc45) · Mode: self-paced /loop, autonomous

Mission

Turn the repo into something more professional: improve code quality, remove trash, update docs, clean package.json, find and debug bugs, Effect V4 everywhere (controller), extract components and logic, keep code DRY.

Standing rules

  • All work lands on loop/professionalize; push after each iteration. Never merge to main (semantic-release fires on main) — final PR at the end.
  • No deploys to pop-os (controller restart kills the running model). Repo-only work.
  • Never delete non-git data files. Deleting dead tracked code is fine (git preserves it).
  • Gates per iteration: controller → bun run typecheck && bun run lint && bun run test:unit; frontend → npm run typecheck && npm run lint (+ targeted tests); full npm run check every ~4 iterations and before the final PR.
  • Commit style: conventional commits, one concern per commit.
  • Respect the instrument-sheet aesthetic; no visual redesigns.
  • SKIP lists from previous loops are binding (controller-simplification items 6–8: do not re-propose).

Backlog (priority order; ✔ = done, ▶ = in progress)

  1. ✔ I1a: Carry over verified keepalive fix (a89bc95b → e956b021).
  2. I1b: Gates actually enforced — add root check:contracts + check:structure job to CI; prune stale environments.ts entry in validate-shared-contracts.mjs; fix stale AGENTS.md test-runner doc (tsx --test → bun test scripts).
  3. I2: Trash removal — empty cli/ stub dir (tracked refs), knip/depcheck dead-export sweep in frontend+controller, dead PROGRESS.md?, stale docs/mockups review (keep mockups, they're design refs).
  4. I3: package.json cleaning — root+frontend+controller: stale scripts, unused deps (depcheck), align engines fields, dedupe config (jscpd threshold drift, knip hoisting → issue #146).
  5. I4: Test story — rename tests/frontend/e2e (it's node:test, not e2e), standardize on bun:test, add frontend unit tests to root check, document in AGENTS.md.
  6. I5: AggregatedSession + contracts seam — move cross-boundary types to shared/contracts; prune validator whitelist.
  7. I6: Collapse per-backend upgrade routes into /runtime/:backend/upgrade (issue #145); split engines/routes.ts god-router by concern (recipes / lifecycle / downloads / runtime).
  8. I7: DRY sweeps — duplicate ps parsers (process-utilities vs process-manager); the two SSE keepalive implementations (http/sse.ts vs chat-completions-stream.ts); per-field route validators (rig-routes hand-rolled parsers → shared request-validation helpers).
  9. I8: Effect V4 deepening (controller) — controller already uses effect@4.0.0-beta.90 in core/command.ts; migrate promise-tangles (engine-coordinator setActiveRecipe phases, download-manager, runtime jobs) to Effect where it reduces complexity. No wholesale rewrite.
  10. I9: EngineSpec deepening — move per-engine command/probe/install/runtime-info bodies into specs/*.ts; unify the 4 "what's installed" paths on RuntimeTarget discovery.
  11. I10: Frontend session-status module — single settleSession/startTurn/isSessionWorking in features/agent/runtime; replace the 3+ inline copies (controller L137, engine L213, applier).
  12. I11: defineAgentRoute scaffold — collapse ~25 in-process agent API route boilerplates.
  13. I12: Component extraction — largest frontend files (query for >400-line .tsx) into model/view pairs per existing convention.
  14. I13: Docs refresh — README accuracy pass, AGENTS.md route map vs reality, controller route map in memory vs actual, CONTEXT.md seed (domain vocabulary) if time allows.
  15. I14: Model-profile table — unify launch parsers (model-runtime-defaults.ts) + streaming quirks (proxy/reasoning.ts) behind one table. CAREFUL: decode-path — verify content fields, not just green tests.
  16. Final: full npm run check, write PR summary, open PR to main, PushNotification.

Iteration log

  • I1 (18:05): Branch created. Recovered keepalive fix via cherry-pick (e956b021) after a stash mishap (old stash@{0} briefly popped; resurrected files parked in scratchpad/old-stash-files; stash entry preserved untouched). I1b: gates CI job added, stale validator entry pruned, AGENTS.md test doc fixed (4a3034a6).
  • I2 (18:20): Trash + config alignment: PROGRESS.md removed, frontend depcheck → .depcheckrc.json, jscpd minTokens aligned at 200 (controller has 0 clones at stricter bar). Issue #146 closed. knip clean in both packages — dead-export debt is already policed by gates.
  • I3 (18:30): Test story: tests/frontend/e2e → tests/frontend/regression (they're node:test module regressions, not e2e); scripts/CI/README/AGENTS renamed to match; frontend unit tests added to root check:frontend. 236/236 pass. NOTE: AGENTS.md forbids --no-verify — loop now commits/pushes with hooks enabled (pushes batched since pre-push runs full check:quality).
  • I4 (18:35): AggregatedSession defined once in shared/agent/session-summary.ts (extends SessionSummary — the old feature-side copy silently omitted cwd/provider/archived/archivedAt that the server actually sends); route + 3 UI consumers import the canonical type.
  • NOTE for final handoff: AGENTS.md requires a desktop rebuild after frontend changes ship — owed once the loop PR merges, not per-iteration.
  • I5 (18:50): Upgrade-route collapse (054c48b5): five per-backend handlers → one /runtime/:backend/upgrade validated against RUNTIME_JOB_BACKENDS; frontend's five upgradeXRuntime methods → one upgradeRuntime(); dropped stale RuntimeCommandPayload (command/args have been rejected server-side since the hardening). #145 closed.
  • I6 (19:05): process-inventory.ts (02c4dcf7): three independent ps parsers unified behind the ProcessRunner seam; listProcesses/buildProcessTree/listProcessTable all derive from listProcessInventory(). 139 unit + 114 integration green.
  • I7 (19:35) — deliberate SKIPS (do not re-propose):
    • SSE keepalive unification: chat path's keepalive is intentionally different from http/sse.ts withSseHeartbeat (immediate first byte before upstream connect = the Cloudflare 502 fix; fixed-interval vs idle-gated; byte-aligned frames vs strings). Unifying restructures the hottest Cloudflare-tuned path to save ~30 lines. Not worth the regression risk.
    • rig-routes Schema rewrite: validators are local, precise, merge-with-current semantics with UI-facing error messages; Schema conversion is churn, not depth.
  • I8 (19:50): session-status module (8e8d83df): SessionStatus union tightened (was | string = no checking; "done" was a tool-block status leaked into the union); isWorkingStatus() replaces session-index's stringly re-derivation; settleTurn/settleTurnFinalizingTools replace 5 copies; SessionTab.status shares the union. All suites green. KNOWN QUIRK (pre-existing): bun test ../tests/frontend scripts combined in ONE invocation fails 1 assertion (build-agent-session-options FRONTEND_BASE) — order/module-resolution cross-talk; CI and all scripts run the suites separately, where both are green.
  • I9 (20:45… actually 18:48 — clock notes below): EngineSpec deepening, mechanical half (d350a867): vllm allowlist filter + Docker JIT wrapper and llama.cpp binary-resolution/ serialization moved from backend-builder into their specs; backend-builder 413→279 lines, now engine-agnostic (generic serialization seam + shared docker-run shape). All gates green. DESIGN-SCOPED SKIP: unifying the four GET /runtime/ info paths — sglang/llamacpp routes use RuntimeTarget discovery while specs use probe chains; they can genuinely disagree, and /runtime/vllm has a different (frontend-typed) response shape. Needs a design decision + live verification; folds into the multi-model/#171 work. Do not flip routes blind.
  • I10 (19:15): docs accuracy (AGENTS.md pi-runtime paths → services/agent-runtime, 3090 gone, Zod→Effect Schema, CLI/voice refs dropped) + NEW chat-proxy end-to-end tests (chat-proxy-forwarding.test.ts): upstream forwarding, keepalive-first-byte SSE contract, model_not_running 503 gate. That coverage did not exist.
  • I11 (19:30): chat handler decomposed into parseChatBody/resolveChatUpstream/ gateOnRunningModel/normalizeCompletionChoices closure stages (behavior pinned by I10 tests; 117/117 integration green). Recipe CRUD: malformed JSON now 400s (ctx.req.json() threw outside the try → 500). SCOPED: Effect-ifying engine-coordinator's setActiveRecipe deliberately NOT attempted autonomously — that's the machinery keeping models alive; Effect adoption stays at boundaries where the repo already uses it (Schema at config/speech/recipes, command effects, coalescer).
  • I12 (20:00): chatterbox modal 750→240 (09947a97) and left sidebar 548→212 (0607f52a), both verbatim-move extractions verified byte-identical markup, all gates green. ⚠️ INCIDENT, resolved: an agent stash cycle over the 15-entry stash pile resurrected an old half-finished "move pi-session usage scanning into agent-runtime" WIP into the tree (broken imports, 2× TS2307). Quarantined — full patch + untracked files preserved in the session scratchpad (quarantine-usage-wip/) and the original stash entry is untouched; affected paths restored to HEAD; stale .next/types purged. NOTE for future loops: the stash pile is a trap — never git stash pop on this repo without checking git stash list first.
  • I13 (19:20): engines god-router split (registerEngineRoutes → recipe/lifecycle/download/ runtime registrars + observed-process factory; routes.ts 387→12). All controller gates green.
  • I14 (19:25): CONTEXT.md seeded — repo domain language (recipes/engines/targets/launch-state, proxy stages, session/turn/pane, contracts/gates) per the architecture-skill discipline.
  • I15 (19:33): git-diff-panel 544→173 (+workflow/diff-view sections, DiffViewMode alias) and recipe-modal 526→126 (+model hook — order preserved — source helpers, summary, footer). All gates green. FLAKE NOTE: one combined bun test scripts run showed 2 fails that vanished on immediate rerun (timing-sensitive usage-policy tests); two consecutive greens after.
  • I16 (19:50): tools/selection-persistence.ts single-owns the ToolSelection wire shape (no discrepancies found between the two sides; persisted JSON byte-identical; type now honest).
  • I17 (19:55): full npm run check + test:integration green end-to-end → PR #181 opened (loop continues appending). FLAGGED FOR OWNER: landing-page.tsx and marketing-page.tsx are ~90% clones and BOTH routed (/landing+/docs vs /agents+/download) — consolidation is the pending marketing product decision, not an autonomous call.
  • I18 (20:10): google-account-modal 501→263 (+setup/connected/load-state sections, 655b38e7).
  • OUTAGE (20:20–06:38): the API session limit cut the night short — the use-setup extraction agent died mid-verification and no wakeups could fire until morning. Nothing was lost: the orphaned extraction was re-verified at 06:38 (all gates green) and committed.
  • WRAP (06:45): deadline passed; final push (27 commits on PR #181), loop stopped. Owed after PR review/merge: desktop rebuild per AGENTS.md; owner decisions on landing-vs-marketing consolidation and the GET /runtime info-path unification design.