Files
geo/progress.md
T
root 4174aafcbc docs: record Phase 21 foreground publish admission
Log the decision to implement publish priority through admission control
and reserved capacity rather than queue sort order, and capture the
preexisting electron.vite.config.ts typecheck mismatch that blocked a
clean desktop-client typecheck run.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 09:44:15 +08:00

413 lines
28 KiB
Markdown

# Progress Log
## 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 `<style>` blocks.
- Restored `AppShell.vue` to the user-preferred version and only moved its inline style attributes into named classes.
- Fixed the broken `pnpm dev:admin` startup path by adding the missing `BrandsView.vue`, running `pnpm install`, and re-running `pnpm typecheck:admin` plus `pnpm dev:admin`.
- Files created/modified:
- `apps/admin-web/package.json` (updated)
- `apps/admin-web/src/i18n/index.ts` (created)
- `apps/admin-web/src/i18n/messages/zh-CN.ts` (created)
- `apps/admin-web/src/i18n/messages/en-US.ts` (created)
- `apps/admin-web/src/main.ts` (updated)
- `apps/admin-web/src/App.vue` (updated)
- `apps/admin-web/src/router/meta.d.ts` (updated)
- `apps/admin-web/src/router/index.ts` (updated)
- `apps/admin-web/src/lib/api.ts` (updated)
- `apps/admin-web/src/lib/display.ts` (updated)
- `apps/admin-web/src/components/PageHero.vue` (created)
- `apps/admin-web/src/components/ArticleDetailDrawer.vue` (created)
- `apps/admin-web/src/components/TemplateGenerationDrawer.vue` (created)
- `apps/admin-web/src/views/LoginView.vue` (updated)
- `apps/admin-web/src/views/WorkspaceView.vue` (updated)
- `apps/admin-web/src/views/TemplatesView.vue` (created)
- `apps/admin-web/src/views/BrandsView.vue` (created)
- `apps/admin-web/src/views/FeatureStubView.vue` (updated)
- `apps/admin-web/src/layouts/AppShell.vue` (updated)
- `packages/shared-types/src/index.ts` (updated)
- `apps/admin-web/src/styles.css` (pending next cleanup pass)
- `task_plan.md` (updated)
- `findings.md` (updated)
- `progress.md` (updated)
### Phase 6: Frontend Scope Recovery
- **Status:** complete
- Actions taken:
- Read the planning files, Claude-side plan artifact, and architecture documents to recover the interrupted task context.
- Confirmed the backend chain is complete locally and the repository still has no `apps/` or `packages/` directories.
- Locked the next useful slice to a tenant-facing `admin-web` foundation rather than platform-side frontend work.
- Files created/modified:
- `task_plan.md` (updated)
- `findings.md` (updated)
- `progress.md` (updated)
### Phase 7: Frontend Foundation
- **Status:** complete
- Actions taken:
- Created the root pnpm workspace, root package scripts, and frontend-oriented `.gitignore`.
- Added shared frontend packages for TS config, API types, and an Axios-based client with auth refresh handling.
- Scaffolded `apps/admin-web` with Vite 8, Vue 3, TypeScript, Ant Design Vue, Pinia, Vue Router, and Vue Query.
- Files created/modified:
- `.gitignore` (created)
- `package.json` (created)
- `pnpm-workspace.yaml` (created)
- `packages/tsconfig/base.json` (created)
- `packages/shared-types/package.json` (created)
- `packages/shared-types/src/index.ts` (created)
- `packages/http-client/package.json` (created)
- `packages/http-client/src/index.ts` (created)
- `apps/admin-web/package.json` (created)
- `apps/admin-web/.env.example` (created)
- `apps/admin-web/index.html` (created)
- `apps/admin-web/tsconfig.json` (created)
- `apps/admin-web/vite.config.ts` (created)
### Phase 8: Admin-Web Initial Features
- **Status:** complete
- Actions taken:
- Implemented the app bootstrap, Ant Design locale wiring, session persistence helpers, and auth store.
- Implemented the login page with seeded local credentials and redirect-aware sign-in flow.
- Implemented the protected shell layout, navigation, quota teaser, workspace dashboard, and placeholder routes for the rest of the information architecture.
- Files created/modified:
- `apps/admin-web/src/App.vue` (created)
- `apps/admin-web/src/main.ts` (created)
- `apps/admin-web/src/styles.css` (created)
- `apps/admin-web/src/lib/session.ts` (created)
- `apps/admin-web/src/lib/errors.ts` (created)
- `apps/admin-web/src/lib/api.ts` (created)
- `apps/admin-web/src/stores/pinia.ts` (created)
- `apps/admin-web/src/stores/auth.ts` (created)
- `apps/admin-web/src/router/meta.d.ts` (created)
- `apps/admin-web/src/router/index.ts` (created)
- `apps/admin-web/src/layouts/AppShell.vue` (created)
- `apps/admin-web/src/views/LoginView.vue` (created)
- `apps/admin-web/src/views/WorkspaceView.vue` (created)
- `apps/admin-web/src/views/FeatureStubView.vue` (created)
### Phase 9: Frontend Verification & Delivery
- **Status:** complete
- Actions taken:
- Ran `pnpm install` for the new workspace and generated `pnpm-lock.yaml`.
- Fixed the initial frontend build errors related to Node typings and typed Axios wrapper method parameters.
- Switched Ant Design Vue registration from full-plugin mode to per-component registration to reduce the main bundle size.
- Ran `pnpm build:admin` successfully and confirmed production assets were emitted.
- Ran `pnpm --filter admin-web preview --host 127.0.0.1 --port 4173` and verified `/login` returned `HTTP/1.1 200 OK` with built asset references.
- Attempted browser automation verification, then fell back to HTTP verification after the local Playwright MCP environment failed on `/.playwright-mcp`.
- After Playwright became usable again, started the Vite dev server plus `tenant-api`, discovered the login CTA was not submitting on click, fixed the handler binding, and re-ran browser verification successfully with Playwright CLI.
- Files created/modified:
- `apps/admin-web/package.json` (updated)
- `apps/admin-web/tsconfig.json` (updated)
- `apps/admin-web/vite.config.ts` (updated)
- `apps/admin-web/src/main.ts` (updated)
- `apps/admin-web/src/views/LoginView.vue` (updated)
- `packages/http-client/src/index.ts` (updated)
- `pnpm-lock.yaml` (created)
- `task_plan.md` (updated)
- `findings.md` (updated)
- `progress.md` (updated)
### Phase 1: Progress Verification
- **Status:** complete
- **Started:** 2026-03-31
- Actions taken:
- Read the task-specific design document.
- Inspected top-level repository layout and backend directory tree.
- Read the planning-with-files skill instructions and initialized planning files.
- Inspected `server/Makefile`, `server/cmd/tenant-api/main.go`, and `server/internal/bootstrap/bootstrap.go`.
- Verified there are 19 migration files and inspected `cmd/dev-seed/main.go`.
- Inspected `sqlc.yaml`, repository directory contents, and current repository integration test placeholders.
- Inspected auth/workspace/template/article/brand services and route registration to compare actual implementation with the design doc.
- Files created/modified:
- `task_plan.md` (created)
- `findings.md` (created)
- `progress.md` (created)
### Phase 2: Gap Analysis and Scope Lock
- **Status:** complete
- Actions taken:
- Compared the repository contents against the design doc's expected `sqlc` and repository layout.
- Confirmed Step 4 is the earliest incomplete milestone because the generated code directory and repository wrappers are missing.
- Ran `make sqlc-generate` and observed a failing schema path in `sqlc.yaml`.
- Files created/modified:
- `task_plan.md` (updated)
- `findings.md` (updated)
- `progress.md` (updated)
### Phase 3: Implementation
- **Status:** complete
- Actions taken:
- Fixed `server/internal/tenant/repository/sqlc.yaml` and regenerated `sqlc` output under `server/internal/tenant/repository/generated/`.
- Added repository wrappers for auth, workspace, template, article, quota, and audit queries.
- Refactored auth/workspace/template services and handlers to use the new repository layer.
- Reworked template generation flow to use repository-backed transactional operations.
- Implemented atomic refresh token rotation in Redis and added `session_store` tests.
- Cleaned existing lint violations that were blocking local verification.
- Files created/modified:
- `server/internal/tenant/repository/sqlc.yaml` (updated)
- `server/internal/tenant/repository/generated/*` (generated)
- `server/internal/tenant/repository/common.go` (created)
- `server/internal/tenant/repository/auth_repo.go` (created)
- `server/internal/tenant/repository/workspace_repo.go` (created)
- `server/internal/tenant/repository/template_repo.go` (created)
- `server/internal/tenant/repository/article_repo.go` (created)
- `server/internal/tenant/repository/quota_repo.go` (created)
- `server/internal/tenant/repository/audit_repo.go` (created)
- `server/internal/tenant/app/auth_service.go` (updated)
- `server/internal/tenant/app/workspace_service.go` (updated)
- `server/internal/tenant/app/template_service.go` (updated)
- `server/internal/shared/auth/session_store.go` (updated)
- `server/internal/shared/auth/session_store_test.go` (created)
- `server/internal/tenant/transport/auth_handler.go` (updated)
- `server/internal/tenant/transport/workspace_handler.go` (updated)
- `server/internal/tenant/transport/template_handler.go` (updated)
### Phase 4: Testing & Verification
- **Status:** complete
- Actions taken:
- Re-ran `make sqlc-generate` after the final code state and confirmed generation succeeds.
- Ran `go test ./...`, then `make test`, and confirmed all tests pass.
- Ran `make lint`, fixed the reported warnings, and re-ran until it passed cleanly.
- Verified the tenant-scope guard script exists and checked for CI workflow files.
- Files created/modified:
- `server/internal/tenant/repository/tx.go` (updated)
- `server/cmd/dev-seed/main.go` (updated)
- `server/internal/shared/auth/middleware_test.go` (updated)
- `server/internal/tenant/app/article_service.go` (updated)
- `server/internal/tenant/app/brand_service.go` (updated)
- `task_plan.md` (updated)
- `findings.md` (updated)
- `progress.md` (updated)
### Phase 5: Delivery
- **Status:** complete
- Actions taken:
- Added backend CI workflow under `.github/workflows/`.
- Added `tenant-scope-guard` to the backend `Makefile` so CI and local verification use the same entrypoint.
- Re-ran `make tenant-scope-guard`, `make test`, and `make lint` after the CI-related edits.
- Updated the backend `Makefile` to run `golang-migrate` through `go run -tags postgres` instead of requiring a preinstalled `migrate` binary.
- Ran `make dev-init` successfully, including Docker startup, migrations, and seed data.
- Started `tenant-api` and verified health endpoints plus auth login/me/refresh/logout behavior with positive and negative checks.
- Files created/modified:
- `.github/workflows/backend-ci.yml` (created)
- `server/Makefile` (updated)
- `task_plan.md` (updated)
- `findings.md` (updated)
- `progress.md` (updated)
## Test Results
| Test | Input | Expected | Actual | Status |
|------|-------|----------|--------|--------|
| Repository inspection | `ls`, `rg --files`, `sed` | Establish current backend coverage | Backend skeleton, migrations, services, and transport files exist | pass |
| Migration count | `find server/migrations -name '*.up.sql' | wc -l` | 19 schema migrations | 19 | pass |
| SQLC generation | `make sqlc-generate` | Generate typed code | Passed after fixing `sqlc.yaml` schema path | pass |
| Go tests | `go test ./...` | All packages compile and tests pass | Passed | pass |
| Make tests | `make test` | Roadmap acceptance command passes | Passed | pass |
| Lint | `make lint` | Roadmap acceptance command passes | Passed after fixing errcheck/ineffassign warnings | pass |
| CI workflow presence | `find . -path '*/.github/workflows/*' -type f` | At least one CI workflow if Step 9 is complete | `.github/workflows/backend-ci.yml` exists | pass |
| Tenant scope guard | `make tenant-scope-guard` | Tenant SQL filter guard passes | Passed | pass |
| Dev init | `make dev-init` | Infra, migrations, and seed complete successfully | Passed after fixing Makefile-managed migrate driver tags | pass |
| Live health | `GET /api/health/live` | HTTP 200 with alive status | Returned `code=0`, `status=alive` | pass |
| Ready health | `GET /api/health/ready` | HTTP 200 with ready status | Returned `code=0`, `status=ready` | pass |
| Login | `POST /api/auth/login` with `admin@geo.local / Admin@123` | Receive access/refresh tokens and user info | Passed | pass |
| Me | `GET /api/auth/me` with fresh access token | Current user payload returned | Passed | pass |
| Refresh | `POST /api/auth/refresh` with original refresh token | Receive rotated access/refresh token pair | Passed | pass |
| Logout revoke | `POST /api/auth/logout`, then `GET /api/auth/me` with old access token | Old access token rejected | Returned `40103 token_revoked` | pass |
| Refresh rotate invalidate | Reuse old refresh token after refresh | Old refresh token rejected | Returned `40121 refresh_session_expired` | pass |
| Workspace overview | `GET /api/tenant/workspace/overview` | Aggregated stats return successfully | Returned `code=0`, article/brand counts present | pass |
| Workspace recent articles | `GET /api/tenant/workspace/recent-articles` | Recent list returns successfully | Returned `code=0` | pass |
| Workspace quota summary | `GET /api/tenant/workspace/quota-summary` | Quota summary returns successfully | Returned `code=0`, balance/total present | pass |
| Workspace template cards | `GET /api/tenant/workspace/template-cards` | Template cards return successfully | Returned `code=0`, count=4 | pass |
| Template generate flow | `POST /api/tenant/templates/{id}/generate` + article detail/version checks | Article generation completes end-to-end | Article `1` completed, versions count `1`, quota `100 -> 99` | pass |
| Brand soft delete and recreate | Create brand, delete, recreate same name | Recreate succeeds after soft delete | Original brand `1` deleted, recreated as brand `2` | pass |
| Question version history | Create question, update, list versions | Version history retained | Returned 2 versions, latest text updated | pass |
| Competitor CRUD basic flow | Create competitor then list | Competitor visible under brand | Returned count `1` | pass |
| Frontend workspace install | `pnpm install` | Workspace dependencies install cleanly | Passed | pass |
| Frontend build | `pnpm build:admin` | `admin-web` compiles and emits production assets | Passed | pass |
| Frontend preview login HTML | `curl -I http://127.0.0.1:4173/login` | Preview route returns `200 OK` | Returned `HTTP/1.1 200 OK` | pass |
| Frontend preview asset shell | `curl -s http://127.0.0.1:4173/login` | HTML references built CSS/JS assets | Returned built asset tags for `index-CtRpygQP.js` and `index-DFz5-Rsr.css` | pass |
| Frontend browser login flow | `pnpm dlx @playwright/test test .tmp-playwright/admin-web.spec.js --reporter=line` | Login succeeds and workspace renders | Passed after binding the login CTA directly to `handleSubmit` | pass |
## Error Log
| Timestamp | Error | Attempt | Resolution |
|-----------|-------|---------|------------|
| 2026-03-31 | None yet | 1 | N/A |
| 2026-03-31 | `make sqlc-generate` failed due to invalid schema path in `sqlc.yaml` | 1 | Fixed by changing schema path to `../../../migrations/` |
| 2026-03-31 | `make lint` failed on several existing warnings | 1 | Fixed all reported warnings and re-ran lint successfully |
| 2026-03-31 | `make dev-init` failed because go-run migrate lacked the postgres driver tag | 1 | Updated `MIGRATE_CMD` to `go run -tags postgres ...` and reran successfully |
| 2026-03-31 | Gemini CLI returned `429 MODEL_CAPACITY_EXHAUSTED` on `gemini-3.1-pro-preview` | 1 | Stopped pursuing Gemini once the user said not to use Gemini |
| 2026-03-31 | Initial frontend build failed on missing Node typings and implicit `any` parameters | 1 | Removed the Node type dependency from app TS config, simplified the Vite config, and typed the API client methods explicitly |
| 2026-03-31 | Playwright MCP browser open failed on `/.playwright-mcp` | 1 | Used preview HTTP verification instead of blocking on browser environment setup |
| 2026-03-31 | Browser click on the login CTA did not submit the form, so Playwright stayed on `/login` | 1 | Added an explicit `@click=\"handleSubmit\"` binding to the CTA and re-ran the E2E flow successfully |
### Phase 21: Foreground Publish Admission
- **Status:** complete
- Actions taken:
- Confirmed the current runtime only starts publish when `state.activeExecutions.size === 0`, so an already-running monitor can block media publish.
- Locked the implementation model: publish is foreground, monitor is background, publish receives reserved runtime capacity, and publish platform policy stays in a lightweight in-memory scheduler.
- Added `apps/desktop-client/src/main/publish-scheduler.ts` with in-memory queueing, same-platform active locks, and 3-6 second platform cooldowns.
- Refactored `runtime-controller.ts` so publish can start while monitor is running, monitor pauses behind any publish backlog, and lease-in-flight is tracked separately for publish vs. monitor.
- Added hardware/runtime adaptive total concurrency with `GEO_DESKTOP_MAX_TOTAL_CONCURRENCY` as an optional cap and a reserved publish slot for monitor budgeting.
- Exposed `publishScheduler` in the desktop runtime snapshot and added scheduler unit tests.
- Verification:
- `pnpm --filter @geo/desktop-client build` passed.
- `pnpm --filter @geo/desktop-client test` passed: 5 files, 26 tests.
- `git diff --check` passed.
- `pnpm --filter @geo/desktop-client typecheck` failed before checking runtime changes because `electron.vite.config.ts` has a Vite 5/8 plugin type mismatch.
## 5-Question Reboot Check
| Question | Answer |
|----------|--------|
| Where am I? | Phase 9 complete |
| Where am I going? | Next useful slice is turning the placeholder routes into real pages, starting with template creation and brand management |
| What's the goal? | Resume the interrupted task by adding the missing `admin-web` frontend foundation on top of the finished backend |
| What have I learned? | The tenant backend is stable enough to support a real login + dashboard frontend slice, and a real browser pass was valuable because it caught a submit wiring bug that static checks missed |
| What have I done? | Added the pnpm frontend workspace, built `apps/admin-web`, wired auth and dashboard data to `tenant-api`, reduced the bundle size, and passed install/build/preview plus browser login verification |