docs(integration): record design freeze fix
This commit is contained in:
1 parent
471e738e77
commit
5bff5d3135
10 files changed
+85
-163
No files matched your search
@@ -1,94 +0,0 @@
|
||||
# Task: Diagnose live AI design freeze after HTTP1 package
|
||||
|
||||
## Identity
|
||||
|
||||
- Task ID: 20260819-design-freeze-live-6e2c
|
||||
- Mode: Feature
|
||||
- Branch: codex/20260819-design-freeze-live-6e2c-design-freeze-live
|
||||
- Worktree: D:\mk-design-freeze-live-6e2c
|
||||
- Base commit: 1ba68a9e41ea5eb4cf03bd11ef18ad61023cd069
|
||||
- Owner: codex-root
|
||||
- Status: Completed
|
||||
|
||||
## Scope
|
||||
|
||||
- Inspect the live installed Makelore process after the combined native-login and HTTP/2-disabled diagnostic package froze in AI Design.
|
||||
- Verify package provenance, Chromium transport flags, process health, TCP state, local Host API responsiveness, session-refresh eligibility, Works service health, and the matching request implementation.
|
||||
- Implement the directly authorized fix in the same task: bound finite AI Design and Works session-refresh requests, prevent implicit replay of non-idempotent requests, and add focused regressions.
|
||||
- Build a Windows diagnostic package that retains native password/SMS login and `disable-http2` so this behavior change can be isolated in the user's next smoke test.
|
||||
|
||||
## Intent And Constraints
|
||||
|
||||
- The user explicitly requested direct execution without sub-agents.
|
||||
- Treat the observed 409, global Loading state, and previous `ERR_HTTP2_PROTOCOL_ERROR` as separate signals until live evidence connects them.
|
||||
- Read the encrypted session only to project expiration/activity metadata and to issue bounded read-only requests; never print or persist access/refresh tokens.
|
||||
- Do not replay the Quote PATCH because its idempotency and server-side commit state are not proven.
|
||||
- Remove every temporary harness and isolated Chromium profile before completion.
|
||||
|
||||
## Outcome
|
||||
|
||||
### Confirmed facts
|
||||
|
||||
- The installed `app.asar` SHA-256 exactly matched the combined diagnostic package: `80948DDBBD5F9BDE9B4C75CB40E515E63200AA79582BF16CF88347DECCD864C6`.
|
||||
- The live Network Service process had `--disable-http2`; HTTP/2 was genuinely disabled.
|
||||
- Main, Renderer, GPU, and Network Service remained Windows-responsive. A three-second sample showed zero Main/Renderer CPU growth and only `0.0156` seconds in Network Service, so the process was passively waiting rather than spinning or blocking the UI thread.
|
||||
- While the UI remained stuck, three rounds of 20 concurrent requests to the live Host API all completed with the expected unauthenticated `401` in `47/16/14 ms`. Main's HTTP event loop and listener were not globally blocked.
|
||||
- The stored access token was more than 157 minutes from expiry and outside the 30-second refresh skew. The shared `refreshFlight` was not active for this incident.
|
||||
- With the same authenticated session, read-only Node probes to `/api/auth/me`, Design capabilities, Workspace list, the affected Workspace, and its two Conversations returned `200` in `31-159 ms`. Works, the account, and that Workspace were not globally locked.
|
||||
- A fresh Electron `43.4.0` Network Service with `disable-http2` returned `200` for the same three read-only endpoints in `1764-1853 ms`. HTTP/1.1 itself remained functional.
|
||||
- Product code gives `net.fetch`, its global-fetch fallback, session refresh, design `authorizedFetch`, IPC Host API requests, Workspace/Conversation loads, and Quote repricing no common deadline or abort contract. Their UI cleanup runs only after the Promise settles.
|
||||
- `proxyAwareFetch` catches every Electron `net.fetch` exception and unconditionally replays the same request with global `fetch`. That is unsafe for mutation methods such as Quote `PATCH` when the first request may have committed before its response transport failed.
|
||||
|
||||
### Conclusion
|
||||
|
||||
- Disabling HTTP/2 did not fix the freeze and is not the root cause.
|
||||
- The live symptom is an unbounded in-process network/IPC Promise in the current Makelore network context. The process remains healthy but a request can wait forever, leaving Renderer loading/busy state waiting for `finally`.
|
||||
- The observed `409` is a completed conflict response and cannot itself block the JavaScript thread. It may be a secondary symptom of the unconditional transport fallback replay after an earlier protocol failure, but that specific mutation was not replayed during this diagnostic task.
|
||||
- The user's “one request hangs, then everything stays Loading” report is consistent with missing deadlines/cancellation plus page-level state ownership, not with a dead request thread.
|
||||
|
||||
### Implemented fix
|
||||
|
||||
- Added a reusable deadline primitive that aborts the active transport and still rejects deterministically when a transport ignores `AbortSignal`.
|
||||
- Bounded the complete AI Design JSON request lifecycle to 30 seconds, including token lookup/refresh, response headers, and response-body parsing. The adapter returns a stable `504 DESIGN_WORKSPACE_REQUEST_TIMEOUT` with `AI 设计服务响应超时,请重试`.
|
||||
- Bounded the shared Works access-token refresh to 30 seconds. All coalesced callers settle together, `refreshFlight` is released by its existing `finally`, and a later refresh can retry without clearing a still-valid refresh token.
|
||||
- Restricted Electron-to-Node fetch fallback to safe reads (`GET`, `HEAD`, `OPTIONS`). `POST`, `PATCH`, `PUT`, and `DELETE` transport failures now propagate without implicitly replaying the mutation.
|
||||
- Preserved native password/SMS login and the temporary global `disable-http2` switch in the diagnostic installer so the user can isolate this request-lifetime/replay fix before HTTP/2 policy is revisited.
|
||||
|
||||
## Verification
|
||||
|
||||
- Live installed-package hash comparison — PASS, exact match.
|
||||
- Live process command-line projection — PASS, Network Service had `disable-http2`.
|
||||
- Live process responsiveness/CPU sampling — PASS, responsive passive wait.
|
||||
- Host API concurrency probe — PASS, 60/60 requests completed within 47 ms per round maximum.
|
||||
- Encrypted-session metadata projection — PASS, no refresh window and no token output.
|
||||
- Authenticated read-only Works differential probes — PASS, account/Design/Workspace/Conversation endpoints responsive.
|
||||
- Fresh Electron HTTP/1.1 differential probe — PASS.
|
||||
- Static request-path inspection — confirmed missing deadlines/AbortSignals and unconditional fallback replay.
|
||||
- Temporary scripts, metadata output, and isolated Electron profile — removed.
|
||||
- Red-phase regression run — PASS as evidence: the new mutation-replay, stuck request, and stuck shared-refresh tests all failed against the previous implementation.
|
||||
- Focused unit tests — PASS, 59/59.
|
||||
- TypeScript check — PASS, `pnpm run typecheck`.
|
||||
- Lint check — PASS with zero errors and seven pre-existing unrelated warnings.
|
||||
- Full unit suite — PASS on clean rerun, 184 files and 2190 tests. The first run had one unrelated Windows port-release timing failure; its focused rerun passed before the clean full rerun.
|
||||
- Production compile — PASS, `pnpm run build:vite`.
|
||||
- Windows package build — PASS after the verified prior uv binary and verified Learning Player artifact were reused when GitHub download timed out.
|
||||
- Packaged Learning Player verification — PASS, SHA-256 `748d6d7c74d9d0ba444e0c051a50010f7070e7d6e46442b1e60f1e2be80fd020`.
|
||||
- Packaged `app.asar` marker inspection — PASS for `disable-http2`, `DESIGN_WORKSPACE_REQUEST_TIMEOUT`, and the request-deadline implementation.
|
||||
- Packaged Electron runtime verification — PASS, including Electron `43.4.0`, Node `24.18.1`, OpenCode, Python, uv, npm, and native addons.
|
||||
- Installer SHA-256 — `FB3BDA4F464770E58EA0AA6E989366685976D5FA7B76E6944B92879B423D83D4`.
|
||||
- Packaged `app.asar` SHA-256 — `A752255B43694814CC3D3FB86C75E024D39E67BBF87BE273960A1FA9FA0366A6`.
|
||||
|
||||
## Follow-ups
|
||||
|
||||
- Smoke the original Quote edit/retry/confirm sequence in the diagnostic package. A stalled request should now leave Loading within 30 seconds and show the explicit timeout message; a transport exception must not produce a second Quote PATCH.
|
||||
- After the user confirms the bounded-request fix, restore HTTP/2 in a separate package and repeat the same regression smoke. `disable-http2` remains a diagnostic variable, not the root-cause fix.
|
||||
- Add privacy-safe request lifecycle instrumentation (`route kind`, transport, phase, elapsed time, deadline outcome, correlation id) so a future live freeze identifies the exact pending boundary without DevTools or credentials.
|
||||
|
||||
## Promotion Candidates
|
||||
|
||||
- Target: `.project-docs/20-architecture/data-flow.md` and the AI Design transport boundary.
|
||||
- Proposal: document the implemented bounded AbortSignal/deadline contract for Main-owned finite Works requests and the prohibition on implicit mutation replay without an explicit idempotency contract.
|
||||
- Evidence: this live differential diagnosis, the focused/full regression results, `electron/utils/proxy-fetch.ts`, `electron/services/works-square-session.ts`, `electron/image-workspace/works-square-workspace.ts`, `src/lib/host-api.ts`, and `src/stores/image-workspace.ts`.
|
||||
- Future impact: network failures become terminal and recoverable instead of leaving permanent Loading state or ambiguously duplicating Quote mutations.
|
||||
- Semantic conflicts: none with ADR-001; Workspace/Conversation ownership remains unchanged.
|
||||
- Human confirmation required: no for a bounded bug fix, but permanent HTTP protocol policy should be decided separately after the fixed package is validated.
|
||||
@@ -0,0 +1,54 @@
|
||||
# Task: Integrate AI design request freeze fix
|
||||
|
||||
## Identity
|
||||
|
||||
- Task ID: 20260819-integrate-design-freeze-3f8b7c
|
||||
- Mode: Integration
|
||||
- Branch: codex/20260819-integrate-design-freeze-3f8b7c-integrate-design-freeze
|
||||
- Worktree: D:\mk-integrate-design-freeze-3f8b7c
|
||||
- Base commit: 9ff79e96813ebadade0aecb8f407edf5aee0144a
|
||||
- Owner: codex-root
|
||||
- Status: Completed
|
||||
|
||||
## Scope
|
||||
|
||||
- Integrate `codex/20260819-design-freeze-live-6e2c-design-freeze-live` at `87e4140f8a7ae3da8dcbf592c8f7604f7fb2ea37` onto the current `main` baseline `9ff79e96813ebadade0aecb8f407edf5aee0144a`.
|
||||
- Preserve the already-combined native password/SMS login and temporary `disable-http2` diagnostic bootstrap.
|
||||
- Promote the durable AI Design request-lifecycle facts into canonical project documentation.
|
||||
- Verify the integrated result before advancing `main`.
|
||||
|
||||
## Intent And Constraints
|
||||
|
||||
- Fix the observed renderer-wide loading state by ensuring Main-owned AI Design requests and shared token refreshes settle within a finite deadline.
|
||||
- Prevent Electron network failures from implicitly replaying mutation requests through Node `fetch`; transparent fallback remains limited to safe reads.
|
||||
- Preserve the existing explicit WebSocket-to-REST fallback contract and its idempotency identity.
|
||||
- Treat `disable-http2` as a temporary diagnostic packaging policy, not as the confirmed root-cause fix.
|
||||
- Do not modify or discard unrelated user work. The checked-out `main` worktree is clean but is still registered to a superseded packaging task, so final promotion must follow the ownership protocol.
|
||||
|
||||
## Outcome
|
||||
|
||||
- Source tip `87e4140f8a7ae3da8dcbf592c8f7604f7fb2ea37` merged without conflict as `471e738e77b8df46ae2ad54b9f5a241a36b0ee0f` on the isolated integration branch.
|
||||
- The integrated tree contains native password/SMS login, temporary `disable-http2`, bounded AI Design requests/token refresh, and safe-read-only low-level transport fallback.
|
||||
- Durable architecture, domain, evidence, current-state, commitment, and task-history records were promoted in integration mode.
|
||||
- The integration branch is complete and verified. Final `main` advancement is handled as a separate promotion task after safely releasing the clean superseded-task ownership on the checked-out main worktree.
|
||||
|
||||
## Verification
|
||||
|
||||
- Pre-merge ancestry check: source tip contains the current `main` baseline.
|
||||
- Merge conflict check — PASS; source merged through Git `ort` with no conflicts.
|
||||
- Frozen dependency install — PASS with pnpm `10.33.4`, 931 packages reused from the local store.
|
||||
- Focused integrated regression — PASS, 7 files / 134 tests covering login, HTTP/2 bootstrap, proxy fallback, Workspace deadlines, and shared token refresh.
|
||||
- TypeScript — PASS, `pnpm run typecheck`.
|
||||
- Lint — PASS with 0 errors and 7 pre-existing warnings, `pnpm run lint:check`.
|
||||
- Full unit suite — PASS, 184 files / 2190 tests, `pnpm test`.
|
||||
- Renderer/Main/Preload/utility production compile — PASS, `pnpm run build:vite`; existing chunk-size/dynamic-import warnings remain non-fatal.
|
||||
- Whitespace validation — PASS, `git diff --check`.
|
||||
|
||||
## Follow-ups
|
||||
|
||||
- Run installed-client real-account Quote PATCH / retry quote / continue-adjusting smoke and verify a stalled request releases the UI within 30 seconds without blocking unrelated calls.
|
||||
- Restore HTTP/2 for a controlled comparison after the finite-lifecycle fix is confirmed; keep `disable-http2` temporary until that evidence exists.
|
||||
|
||||
## Promotion Candidates
|
||||
|
||||
- Accepted into `20-architecture/data-flow.md`, `20-architecture/system-overview.md`, `40-domain/business-rules.md`, `30-worklog/current-state.md`, `50-evidence/evidence-index.md`, and `80-commitments/commitments.md`.
|
||||
@@ -1,60 +0,0 @@
|
||||
# Task: Integrate native login and HTTP2-disabled diagnostic package
|
||||
|
||||
## Identity
|
||||
|
||||
- Task ID: 20260819-native-http1-package-c7e4
|
||||
- Mode: Integration
|
||||
- Branch: codex/20260819-native-http1-package-c7e4-native-http1-package
|
||||
- Worktree: D:\mk-native-http1-package-c7e4
|
||||
- Base commit: 9ff79e96813ebadade0aecb8f407edf5aee0144a
|
||||
- Owner: codex-root
|
||||
- Status: Completed
|
||||
|
||||
## Scope
|
||||
|
||||
- Integrate the completed native password/mobile-code login change from commit `5a048da8a615792dee9e0c76b6fda814aaa1b854`.
|
||||
- Integrate the temporary Electron HTTP/2 diagnostic bootstrap from commit `411cd9cedfeb14df0c839e6e1cbf1110826ad0e6`.
|
||||
- Produce and verify a Windows x64 diagnostic installer without promoting either change to the default branch.
|
||||
|
||||
## Intent And Constraints
|
||||
|
||||
- Preserve the Main-owned authentication boundary: Renderer login requests continue through Host API routes.
|
||||
- Replace the failing browser desktop-auth flow with the already completed password and mobile verification-code surfaces.
|
||||
- Keep `app.commandLine.appendSwitch('disable-http2')` before the single-instance lock and `app.whenReady()` so every Electron network context inherits the diagnostic switch.
|
||||
- Treat this as an isolated diagnostic package. The default branch and canonical current-state snapshot are not advanced by this task.
|
||||
- Use the project-pinned Python runtime and verified `uv 0.10.0`; do not reuse the earlier native-login package's temporary `uv 0.10.9` substitution.
|
||||
- The user explicitly requested direct execution without sub-agents, so verification was performed in the primary task.
|
||||
|
||||
## Outcome
|
||||
|
||||
- Merged native login as integration commit `3ba90af` and HTTP/2 disablement as integration commit `c1548e6` with no conflicts.
|
||||
- Generated `D:\mk-native-http1-package-c7e4\release\Makelore-2.0.0-win-x64.exe`.
|
||||
- Installer size: `302025649` bytes.
|
||||
- Installer SHA-256: `2A81ECC39A55E3F01ED90A8D1D564E020E82671779E72B50EB76282197D31EC2`.
|
||||
- Authenticode status: `NotSigned`, consistent with the local diagnostic-package environment.
|
||||
- Final `app.asar` contains the password login, mobile login, SMS-code and image-code routes and native login UI, while `/api/auth/browser/start` is absent.
|
||||
- Final `app.asar` contains `disable-http2` before both `requestSingleInstanceLock` and `whenReady` in the packaged Main bootstrap.
|
||||
|
||||
## Verification
|
||||
|
||||
- `pnpm exec vitest run tests/unit/http2-diagnostic-bootstrap.test.ts tests/unit/auth-routes.test.ts tests/unit/auth-store.test.ts tests/unit/login-page.test.tsx tests/unit/works-square-session.test.ts tests/unit/works-square-session-persistence.test.ts tests/unit/works-square-session-persistence-policy.test.ts --reporter=dot` — PASS, 7 files / 98 tests.
|
||||
- `pnpm run typecheck` — PASS.
|
||||
- Scoped ESLint over the changed Main, Renderer, E2E and unit-test files — PASS.
|
||||
- `pnpm test` — PASS, 184 files / 2185 tests.
|
||||
- `pnpm run build:vite` — PASS.
|
||||
- Electron smoke test `can skip setup and open the native login surface` — PASS, 1 test.
|
||||
- `pnpm run package:stage:win-x64` with the verified Learning Player artifact — PASS.
|
||||
- `node scripts/run-electron-builder.mjs --win --publish never` — PASS.
|
||||
- `pnpm run verify:publish-runtime` — PASS, npm `11.6.2`.
|
||||
- `pnpm run verify:artifact:win -- --allow-dirty --installer .\release\Makelore-2.0.0-win-x64.exe` — PASS; Electron `43.4.0`, Node `24.18.1`, OpenCode `1.18.9`, Python runtime present, `uv 0.10.0`, native addons present.
|
||||
- `node scripts/verify-learning-player-artifact.mjs release\win-unpacked\resources\resources\learning-player` — PASS, SHA-256 `748d6d7c74d9d0ba444e0c051a50010f7070e7d6e46442b1e60f1e2be80fd020`.
|
||||
- Direct packaged `app.asar` assertions for the HTTP/2 switch ordering, native auth routes/UI and removal of the legacy browser-start route — PASS.
|
||||
|
||||
## Follow-ups
|
||||
|
||||
- Install this diagnostic package and confirm that password/mobile-code authorization succeeds against the live Works service.
|
||||
- Reproduce the generation-quote request sequence. If the global loading freeze still occurs, the result rules out HTTP/2 as the sole cause and request ownership/cancellation in the quote flow should be instrumented next.
|
||||
|
||||
## Promotion Candidates
|
||||
|
||||
- None from this packaging task. Promotion of native login or temporary HTTP/2 disablement remains an explicit default-branch integration decision after live validation.
|
||||
Reference in new issue
Block a user