# Progress Log ## 2026-07-14T18:45:00+08:00 - Local same-platform challenge circuit breaker started - User screenshot disproved the previous end-to-end assumption: after `monitoring_collect:7995` hit `doubao_challenge_required`, later Doubao task `7989` still attempted collection on the same single account. - Added Phases 66-68 to reproduce the local queue race, add a platform circuit breaker, and verify it without changing other-platform scheduling or multi-account failover. - Initial direction: cancel/remove already leased or queued same-platform work locally as soon as the last usable account becomes challenged; do not wait for server bulk status propagation. - Refined the screenshot diagnosis: later Doubao row `7989` has attempt 0, so it was not proven to reach the adapter; it was bulk-marked failed with the original challenge error, which is still the wrong cancellation state. - Added two red regressions. Desktop scheduler fails because no platform-level pending-task removal function exists; server test fails because later tasks are explicitly set to `failed` with no `skip_reason`. - Phase 66 is complete and Phase 67 implementation is in progress. - Desktop scheduler/runtime circuit-breaker changes applied successfully. The first combined server patch failed context verification and made no server edits; implementation continues with smaller exact-context patches. - Scheduler/account-pool focused tests now pass. First typecheck found one redundant event payload field; the server regression reached the new `skipped` SQL and now only needs updated argument assertions. - Implemented local platform circuit breaking, atomic same-platform pending-task removal, manual probe/rebind recovery, model-wide monitor cancellation across account targets, canceled lifecycle events, and skipped monitoring follow-ups. - Focused desktop tests pass (3 files / 12 tests), desktop typecheck passes, focused server authorization-cancellation tests pass, and `git diff --check` passes. - Full verification passes: desktop 31 files / 213 tests, desktop typecheck, desktop production build, and server-wide `go test ./...`. - Final diff review found no debug instrumentation, whitespace errors, or unintended projection changes. - Phase 68 is complete. Live captcha triggering was not repeated against the user's account; the screenshot sequence is covered deterministically at the local scheduler and server terminal-state boundaries. - Root cause: follow-up tasks were already prevented from adapter execution in the shown case (`attempt 0`) but were bulk-recorded as failed with the original challenge message, and the client lacked immediate platform-wide queue purging. The fix addresses both the misleading state and the local race. - Planning completion check still reports historical unfinished phases 11/12, 17, and 48/49 from earlier roadmap work; current follow-up phases 66-68 are complete and unrelated roadmap state was preserved. ## 2026-07-14T00:00:00+08:00 - Human-verification failover and alert hardening started - Added Phases 63-65 for challenge reproduction, account-scoped failover, model-level cancellation, and desktop system notifications. - Recovered the latest multi-account context: same-platform account pooling already exists, while Doubao challenge handling currently blocks the platform at admission and surfaces only activity/page state rather than a guaranteed OS notification. - Added `runtime-system-notification.test.ts` for danger alerts, forced account-challenge alerts, per-account deduplication, and notification failure isolation. - Red test confirmed the missing seam: Vitest fails because `runtime-system-notification` does not exist yet. - Implemented the Electron-free notification policy/sink with 30-second per-error deduplication and exception isolation. - Wired all `danger` runtime activities plus challenge/risk-control account transitions into the sink. - Added native delivery through Windows tray Toast and Electron notifications on macOS/Linux, configured once during desktop bootstrap. - Focused notification/account-pool tests pass (2 files, 8 tests); desktop Vue/TypeScript typecheck passes. - Added a direct server regression test for final `doubao_challenge_required` handling. It verifies same-tenant/date/model/client scoping, current-task exclusion, terminal source statuses, bound arguments, and the authorization-block payload. - The focused server test set passes, including existing non-retryable and target-client precedence checks. - Full verification passes: desktop 31 files / 212 tests, desktop typecheck, desktop production build, server `internal/tenant/app` tests, and `git diff --check`. - Final diff review confirmed ordinary recoverable warnings stay in the activity feed, while `danger` errors and account challenge/risk-control transitions produce native system notifications. - Phase 65 is complete. Automated coverage cannot click the host OS notification center, but the Electron native notification path passes typecheck and production bundling. - The planning skill completion check reports historical unfinished phases 11/12, 17, and 48/49 from earlier work; current request phases 63-65 are all complete and were not used to rewrite unrelated roadmap state. - Files changed for this scope: - `apps/desktop-client/src/main/runtime-system-notification.ts` (created) - `apps/desktop-client/src/main/runtime-system-notification.test.ts` (created) - `apps/desktop-client/src/main/runtime-controller.ts` - `apps/desktop-client/src/main/bootstrap.ts` - `apps/desktop-client/src/main/tray.ts` - `server/internal/tenant/app/monitoring_callback_service_test.go` - planning files ## Session: 2026-04-30 ### Phase 37: k3s Deployment Foundation - **Status:** complete - Actions taken: - Recovered the existing Docker Compose deployment topology and runtime command set. - Added a self-contained `deploy/k3s` kustomize deployment with namespace, config, placeholder secrets, infra StatefulSets, app Deployments/Services, migration/minio-init Jobs, and Traefik Ingress. - Included all server-side runtime services: `tenant-api`, `worker-generate`, `kol-assist-worker`, `scheduler`, `ops-api`, plus `frontend` and `ops-web`. - Added `Dockerfile.ops-web` so the operations frontend can be built as a deployable nginx image. - Updated the offline packaging script to build/save `ops-api`, `kol-assist-worker`, and `ops-web`, and to include the k3s directory in generated deploy packages. - Updated the offline compose override and `.env.example` with the missing ops/security knobs. - Files created/modified: - `Dockerfile.ops-web` (created) - `deploy/k3s/` (created) - `deploy/docker-compose.yaml` (updated) - `deploy/scripts/package.sh` (updated) - `deploy/docker-compose.offline.yaml` (updated) - `deploy/.env.example` (updated) - `task_plan.md` / `findings.md` / `progress.md` (updated) ### Phase 38: k3s Verification - **Status:** complete - Verification: - `kubectl kustomize deploy/k3s` rendered 30 Kubernetes objects. - Local YAML parsing of the rendered manifest passed. - `bash -n deploy/scripts/package.sh && bash -n deploy/scripts/load-and-start.sh` passed. - `git diff --check` passed. - `pnpm --filter ops-web build` passed. - `pnpm --filter admin-web typecheck` passed. - Notes: - `kubectl apply --dry-run=client` could not complete locally because the configured kube-apiserver at `127.0.0.1:26443` is not running; run live API validation on the target k3s node. ## Session: 2026-04-20 ### Phase 20: Tracking Collect-Now Repair - **Status:** complete - Actions taken: - Re-read the `admin-web` tracking page, monitoring API client, and tenant monitoring handler/service chain to isolate why `立即采集` still depended on the removed browser-plugin runtime. - Confirmed the frontend was still blocking on `monitoring-plugin` readiness and trying to kickoff a plugin cycle even though monitoring collection is now meant to run silently through `desktop-client`. - Added monitoring dashboard runtime state so the page now knows whether the current logged-in user's own desktop client is online. - Tightened `collect-now` server validation to only accept requests when the current actor has an online desktop client, instead of falling back to another online client in the same workspace. - Updated `TrackingView.vue` to remove the plugin kickoff path, call only the backend `collect-now` endpoint, and disable the CTA with an explicit reason tooltip when brand/keyword/client-online requirements are not met. - Added the missing `desktop_client_offline` frontend error mapping plus new i18n strings for the button gating reasons. - Files created/modified: - `task_plan.md` (updated) - `findings.md` (updated) - `progress.md` (updated) - `apps/admin-web/src/views/TrackingView.vue` (updated) - `apps/admin-web/src/i18n/messages/zh-CN.ts` (updated) - `apps/admin-web/src/i18n/messages/en-US.ts` (updated) - `apps/admin-web/src/lib/errors.ts` (updated) - `packages/shared-types/src/index.ts` (updated) - `server/internal/tenant/app/monitoring_service.go` (updated) ### Phase 15: Desktop Scheduler Design & Integration - **Status:** complete - Actions taken: - Re-read the planning files and recovered the current desktop AI monitoring scope from the existing repo changes. - Audited the desktop runtime controller, process metrics sampler, runtime snapshot, session registry, and monitor adapter surface. - Confirmed the current desktop task executor is global-serial, monitor-task staleness dropping is already implemented, and no durable local queue/cache exists yet. - Confirmed `playwright-core` is installed but `connectOverCDP()` is not wired, while hidden Electron execution already exists via `BrowserWindow` and `WebContentsView`. - Added `monitor-scheduler.ts` as a durable file-backed local scheduler for monitor tasks, including same-day persistence, stale cross-day pruning, per-platform mutual exclusion, question-level cooldowns, and lease-miss backoff. - Refactored `runtime-controller.ts` so publish tasks keep a conservative explicit queue while monitor tasks are selected through the local scheduler with adaptive max concurrency from Electron process metrics. - Extended runtime diagnostics to surface the monitor scheduler snapshot and made the lease manager track multiple active leases instead of a single global lease placeholder. - Files created/modified: - `task_plan.md` (updated) - `findings.md` (updated) - `progress.md` (updated) - `apps/desktop-client/src/main/monitor-scheduler.ts` (created) - `apps/desktop-client/src/main/runtime-controller.ts` (updated) - `apps/desktop-client/src/main/lease-manager.ts` (updated) - `apps/desktop-client/src/main/runtime-snapshot.ts` (updated) ### Phase 16: Hidden Playwright CDP Execution Layer - **Status:** complete - Actions taken: - Added `playwright-cdp.ts` as a reusable hidden-browser manager that launches hidden Electron `BrowserWindow` instances on account-bound sessions and attaches Playwright via `chromium.connectOverCDP()`. - Enabled Electron remote debugging in bootstrap so the app exposes a CDP endpoint for local Playwright attachment. - Extended adapter context with an optional Playwright `{ browser, page }` handle and wired the runtime controller to acquire/release hidden Playwright pages when an adapter declares `executionMode: "playwright"`. - Kept the existing hidden `WebContentsView` path intact so current adapters like Doubao continue to work unchanged. - Files created/modified: - `apps/desktop-client/src/main/playwright-cdp.ts` (created) - `apps/desktop-client/src/main/bootstrap.ts` (updated) - `apps/desktop-client/src/main/adapters/base.ts` (updated) - `apps/desktop-client/src/main/runtime-controller.ts` (updated) ### Phase 17: Verification & Delivery - **Status:** in_progress - Actions taken: - Added optional scheduler metadata to desktop task events in shared types and server publishers so the local scheduler can make safer fan-out decisions before leasing. - Ran `gofmt` on the modified Go files after the event metadata changes. - Verified `pnpm --filter @geo/desktop-client typecheck` passes. - Verified `pnpm --filter @geo/desktop-client build` passes. - Verified `pnpm --filter admin-web typecheck` still passes after the shared-type event additions. - Verified `go test ./internal/tenant/app/...` passes from `server/`. - Files created/modified: - `packages/shared-types/src/index.ts` (updated) - `server/internal/tenant/app/desktop_task_events.go` (updated) - `server/internal/tenant/app/desktop_task_service.go` (updated) - `server/internal/tenant/app/publish_job_service.go` (updated) ### Phase 18: Qwen Adapter & Auth Relaxation - **Status:** complete - Actions taken: - Ported the browser-extension `qwen` monitoring flow into a new desktop Playwright adapter that drives Tongyi's in-page managers via `page.evaluate()` and extracts answer/source data from `__qianwenChatAPI`. - Registered the new `qwen` monitor adapter in the desktop runtime so monitor tasks can execute through the hidden Playwright CDP layer. - Tightened generic AI auth fingerprinting to ignore CSRF-only cookies like `XSRF-TOKEN`, which Qwen sets even for anonymous visits. - Added a Qwen-specific bind detector so the auth window can auto-close once a real session footprint is present, even if the page has not yet rendered an obvious avatar/name signal. - Updated monitor preflight policy so only `yuanbao`, `kimi`, and `deepseek` require active login before execution; `qwen`, `doubao`, and `wenxin` are allowed to run anonymously when needed. - Files created/modified: - `task_plan.md` (updated) - `findings.md` (updated) - `progress.md` (updated) - `apps/desktop-client/src/main/adapters/qwen.ts` (created) - `apps/desktop-client/src/main/adapters/index.ts` (updated) - `apps/desktop-client/src/main/runtime-controller.ts` (updated) - `apps/desktop-client/src/main/account-binder.ts` (updated) ### Phase 19: Qwen Verification & Delivery - **Status:** complete - Actions taken: - Verified `pnpm --filter @geo/desktop-client typecheck` passes after the Qwen adapter, bind-flow, and auth-policy updates. - Verified `pnpm --filter @geo/desktop-client build` passes after the same changes. - Followed up on a real Qwen bind stall reported by the user, inspected the machine's persisted `pending-qwen-*` partition, and confirmed logged-in cookies like `tongyi_sso_ticket`, `tongyi_sso_ticket_hash`, and `b-user-id` are present. - Reworked Qwen account detection so bind/probe can succeed from those persisted auth cookies even when the page nickname/avatar heuristics do not trigger. - Files created/modified: - `task_plan.md` (updated) - `findings.md` (updated) - `progress.md` (updated) ## Session: 2026-04-04 ### Phase 13: Prompt Centralization - **Status:** complete - Actions taken: - Read the current planning files and reopened repository context for the new prompt-centralization request. - Searched runtime and seed paths for all currently used hard-coded prompts instead of only matching the obvious template seed strings. - Confirmed the prompt surface spans template seeds, template generation fallback prompts, template assist fallback prompts, prompt-rule generation supplements, and knowledge prompt injection. - Added a dedicated `server/internal/tenant/prompts` package to centralize platform template seed prompts and runtime prompt fragments. - Refactored `cmd/dev-seed`, `template_prompt.go`, `template_assist.go`, `prompt_generate_service.go`, and `knowledge_service.go` to read prompt text from the new package. - Corrected invalid JSON quoting in the seed `custom_placeholder` fields while moving the template card-config blobs. - Files created/modified: - `task_plan.md` (updated) - `findings.md` (updated) - `progress.md` (updated) - `server/internal/tenant/prompts/runtime.go` (created) - `server/internal/tenant/prompts/template_seeds.go` (created) - `server/cmd/dev-seed/main.go` (updated) - `server/internal/tenant/app/template_prompt.go` (updated) - `server/internal/tenant/app/template_assist.go` (updated) - `server/internal/tenant/app/prompt_generate_service.go` (updated) - `server/internal/tenant/app/knowledge_service.go` (updated) ### Phase 14: Prompt Verification & Delivery - **Status:** complete - Actions taken: - Ran `gofmt` across all changed Go files after the prompt extraction. - Re-scanned the runtime and seed callers to confirm the long prompt literals were removed from business functions and now only live under `server/internal/tenant/prompts`. - Ran `go test ./internal/tenant/... ./cmd/dev-seed` from `server/` and confirmed the affected packages compile and tests pass. - Files created/modified: - `task_plan.md` (updated) - `findings.md` (updated) - `progress.md` (updated) ## Session: 2026-03-31 ### Phase 10: Interface Coverage Audit & Visual Mapping - **Status:** complete - Actions taken: - Re-read the backend router and transport/app layers to inventory every currently exposed tenant-facing HTTP interface. - Confirmed the remaining frontend-backed API groups are `templates/articles` and `brands`, while `custom/media/tracking/knowledge` still lack matching backend routes in this repo. - Recovered the reference screenshot layouts with position-aware OCR so the implementation can follow actual placement and grouping instead of just textual labels. - Files created/modified: - `task_plan.md` (updated) - `findings.md` (updated) - `progress.md` (updated) ### Phase 11: Admin-Web Full Interface Delivery - **Status:** in_progress - Actions taken: - Added a minimal `vue-i18n` setup with `zh-CN` and `en-US` message bundles, locale persistence, and Ant Design locale switching. - Reworked `LoginView`, `WorkspaceView`, `TemplatesView`, `ArticleDetailDrawer`, `TemplateGenerationDrawer`, `PageHero`, and `BrandsView` to stop using inline styles and to use component-local `