Compare commits
3
Commits
d7f936db94
...
c2c415c674
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c2c415c674 | ||
|
|
8a67e8bd47 | ||
|
|
1d00ba39bd |
No files matched your search
@@ -4,6 +4,8 @@ This file is the integrated default-branch snapshot. Feature tasks record progre
|
||||
|
||||
## Integrated Through
|
||||
|
||||
- 2026-09-14:任务 `20260914-merge-cloud-reconnect-8fe72c41` 经用户授权移交主目录登记,将源 `8a67e8bd47d814b533476a6e36421f7a5d983a27` 无冲突快进合入本地 `main`。云智能体 Main 凭证处理不再因签发端轻微快于客户端而拒绝正常的五分钟凭证,改为限制本地复用时长;服务端过期校验及既有刷新余量不变。产品树与已验证源一致,沿用 33 项相关测试、类型检查、scoped ESLint 和 Vite 全目标构建。该缺陷已复现,尚不能据此认定线上所有不可用提示均由此引起;详见[源任务](tasks/20260914-cloud-reconnect-5ad71e6c.md)。原有三份未跟踪文档保留;需要重新打包安装客户端才生效,未推送、打包、安装或部署。
|
||||
|
||||
- 2026-09-14:任务 `20260914-merge-ppt-makelore-2e8ec5dc` 经用户授权移交主目录登记,将已独立审查的 `4f2caf7` 从 `9044f7d` 无冲突快进合入本地 `main`。新建云智能体默认 300 步,保留显式 40/自定义设置;微信会话优先展示原生 Run 状态及失败原因,再显示部分正文,涵盖关闭历史会话与仅排队状态。产品树与已验证源一致,沿用 42 项回归、类型检查、lint、Vite 构建及 Electron 验收,详见[源任务](tasks/20260914-makelore-ppt-failure-7c4a.md)。原有三份未跟踪文档保留;未推送、打包、安装或部署。需配套更新 Yuxi API/worker,已有智能体调整限制后重新发布。
|
||||
|
||||
- 2026-09-14:任务 `20260914-merge-agents-entry-aecd607d` 经用户确认主目录登记移交,将源 `9317d0acc7cfa6eab2379ab37acefbac8e435fad` 无冲突快进合入本地 `main`。Agents 入口换为蓝紫色全息智能体插画,标语为“打造你想象中的AI助手”,顺序为 Agents、Code、Canvas、Robot;源记录原样导入,产品树与已验证源一致,沿用其类型检查、相关单测、构建和 Electron 双窗口验证。原有 3 份未跟踪文档保持原样;未推送、打包、安装或部署。详见[源任务](tasks/20260914-agents-entry-art-0242f8f3.md)。
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
# Task: 诊断云智能体客户端频繁不可用
|
||||
|
||||
## Identity
|
||||
|
||||
- Task ID: 20260914-cloud-reconnect-5ad71e6c
|
||||
- Mode: Feature
|
||||
- Branch: codex/20260914-cloud-reconnect-5ad71e6c-cloud-reconnect
|
||||
- Worktree: D:\Datas\OthersProjects\.codex-worktrees\makelore\20260914-cloud-reconnect-5ad71e6c
|
||||
- Base commit: 1d00ba39bd598e2f2ea26cc867d82afc2bdba3ee
|
||||
- Owner: codex
|
||||
- Status: Ready for Integration
|
||||
|
||||
## Scope
|
||||
|
||||
- Diagnose frequent unavailable errors in the installed cloud Agent/channel pages. Repair the reproduced Main session time-validation defect, keeping channel routing, credentials, request identity and mutation recovery unchanged.
|
||||
|
||||
## Intent And Constraints
|
||||
|
||||
- Concurrent Gate passed through official check/start/status; exact identity, isolated feature worktree and main base match above. Planning Gate passed after required entries, own task, positioning/current state, decisions/architecture, ADR-004, personal cloud Agent ADR, domain and evidence/reflection/commitment context. Peer Scope/Intent/Promotion context was assessed read-only; historical placeholders are unknown. Related channel/Agent diagnostics and UX discussion are read-only, completed, or on earlier fixed bases, with no concrete semantic conflict affecting this narrow Main repair.
|
||||
- Credentials/network remain Main-owned. The user subsequently authorized committing the verified repair and merging it into main. No production model request, mutation replay, reconnect, account change, subagent, push, package, installation or deployment is included.
|
||||
- Merge preparation resumed this same task through official start/status; Concurrent and Planning Gates passed using the previously loaded context and refreshed changed UX discussion record. The separate integration start was blocked by main's previous integration owner, 20260914-merge-ppt-makelore-2e8ec5dc; transferring that registration requires explicit confirmation. Main and its three pre-existing untracked documents remain untouched.
|
||||
- Diagnosis uses actual CloudAgentsModule code with controlled session responses. Valid upstream 200 is insufficient: the asserted signal includes whether Main emits the next Yuxi read.
|
||||
|
||||
## Outcome
|
||||
|
||||
- Confirmed defect: with the issuer one second ahead, a normal 300-second session is rejected by the client upper-bound comparison against local Date.now; the client emits cloud_service_unavailable and never calls /api/makelore/agents. Equal clocks pass the identical harness.
|
||||
- Supplied production API logs contain only successful internal session issuance every approximately 30 seconds; they do not contain the failing client reads. Local installed 1.5.2 Main logs do not record these errors. Anonymous Works HTTP Date probes show subsecond offsets but do not prove the deployed Yuxi session claims or this incident's sole cause. Public Yuxi URL requested for the remaining network check.
|
||||
- Fixed Main by capping local session reuse at 300 seconds instead of rejecting normal issuer expiry for clock skew. Existing expiry, finite integer timestamp, account, scope, bearer and HTTPS checks remain. No mutation retry or new channel behavior was added.
|
||||
- Read-only inspection of the running installed 1.5.2 app.asar confirms the same faulty expires_at > Date.now() + 300000 clause is present. The installation was not altered or restarted. This record accompanies the verified source repair for integration; the installed app remains unchanged.
|
||||
|
||||
## Verification
|
||||
|
||||
- Read-only stdin Node/TypeScript harness ran the actual Main module: clock offset 0 => PASS, session + agents requested; offset +1000 ms => FAIL, cloud_service_unavailable, only session requested. No production credentials used.
|
||||
- Formal regression was added before the fix: 1 failing skew test / 3 passing expired-invalid timestamp cases. Failure stack identifies CloudAgentsModule.session; with the fix all 33 Main cloud Agent tests pass, including cache reuse and renewal at the existing five-second margin.
|
||||
- Pinned pnpm 10.33.4 frozen offline dependency install completed. Typecheck, scoped ESLint, production Renderer/Main/Preload/utility build, and git diff --check passed. Build emits existing Browserslist-age/dynamic import notices. No full suite, new installer, live authenticated end-to-end check or production operation is claimed; no visible UI flow changed, so the actual Main session test is the relevant regression seam.
|
||||
|
||||
## Follow-ups
|
||||
|
||||
- Correlate the deployed public Yuxi path and failed Main response; production incident attribution remains provisional until that evidence exists.
|
||||
- Rebuilt desktop installation required to deliver any Main fix. Do not change cloud configuration or bindings based only on this repro.
|
||||
|
||||
## Promotion Candidates
|
||||
|
||||
- Target: current-state.md / Integrated Through. Record this narrow Main credential clock-skew repair and its source commit after merge. Evidence: actual Main reproduction, 33 passing tests, typecheck, scoped lint and production build. Future impact: correctly issued credentials can be accepted across slight client/issuer clock differences; local reuse stays capped. No conflict with ADR-004 or personal cloud Agent ownership. Main integration is authorized; registration transfer requires confirmation. No broader production root-cause claim or architecture change is proposed.
|
||||
@@ -0,0 +1,42 @@
|
||||
# Task: 合并云智能体连接时差修复
|
||||
|
||||
## Identity
|
||||
|
||||
- Task ID: 20260914-merge-cloud-reconnect-8fe72c41
|
||||
- Mode: Integration
|
||||
- Branch: main
|
||||
- Worktree: D:\Datas\OthersProjects\makelore
|
||||
- Base commit: 1d00ba39bd598e2f2ea26cc867d82afc2bdba3ee
|
||||
- Owner: codex
|
||||
- Status: Ready for Integration
|
||||
|
||||
## Scope
|
||||
|
||||
- Integrate the verified MakeLore cloud session clock-skew repair 8a67e8bd47d814b533476a6e36421f7a5d983a27 onto local main and record its source evidence. No Yuxi, Works Square or AgentBus product changes.
|
||||
|
||||
## Intent And Constraints
|
||||
|
||||
- User authorized the merge, then explicitly approved releasing previous main owner 20260914-merge-ppt-makelore-2e8ec5dc and adopting the existing three untracked task documents unchanged. Official check/start/status established matching integration ownership and repository integration lock.
|
||||
- Concurrent, Planning and Integration Gates passed. Reused unchanged loaded positioning, decisions (ADR-004 and personal cloud Agents), architecture/domain, evidence/reflections/commitments and historical peer scopes; refreshed current-state, own/source records and concurrent UX record. UX continuation owns Renderer creation/configuration/preview, preserves authentication contracts and has no semantic conflict with this narrow Main expiry repair. Historical incomplete records remain unknown, with no concrete dependency here.
|
||||
- Main retains credential/network authority and current identity, scope, HTTPS, account isolation and mutation recovery behavior. Source task records are imported unchanged. No push, packaging, installation, deployment, subagent or cleanup is authorized by the merge.
|
||||
|
||||
## Outcome
|
||||
|
||||
- Local main fast-forwarded without conflicts from 1d00ba39bd598e2f2ea26cc867d82afc2bdba3ee to source 8a67e8bd47d814b533476a6e36421f7a5d983a27. Main now caps credential cache reuse instead of rejecting a normal credential when the issuer clock is slightly ahead.
|
||||
- Promoted the narrow implementation and verification facts into current-state / Integrated Through. No broader architecture decision or exclusive production root-cause claim was made. Installed MakeLore remains unchanged.
|
||||
- The original three untracked task documents were retained and excluded from staging. Integration documentation is limited to this own record and current-state.
|
||||
|
||||
## Verification
|
||||
|
||||
- Source actual Main reproduction exposed rejection at +1000 ms issuer skew; source regression now passes all 33 Main cloud Agent tests, including expired/invalid claims and cache renewal at the existing five-second margin. Source typecheck, scoped ESLint, production Vite Renderer/Main/Preload/utility build and diff check passed.
|
||||
- Fast-forward preserved the exact verified source tree, so no product/test rewrite required repeated builds. Post-merge tree comparison to 8a67e8b passed before integration notes; final product/source-record equality and task-aware drift check confirm the documentation-only integration commit and unchanged adopted documents.
|
||||
- No new installer, live authenticated end-to-end check or production model operation was performed. Logs containing only session issuance HTTP 200 fit the reproduced defect but do not prove it is the sole production cause.
|
||||
|
||||
## Follow-ups
|
||||
|
||||
- Rebuild and install the desktop client to deliver this Main fix. Optional production endpoint/request correlation remains useful if failures persist after upgrade.
|
||||
- Source worktree D:\Datas\OthersProjects\.codex-worktrees\makelore\20260914-cloud-reconnect-5ad71e6c remains present on branch codex/20260914-cloud-reconnect-5ad71e6c-cloud-reconnect. Ask separately about cleanup after the merge; preserve branch and commit.
|
||||
|
||||
## Promotion Candidates
|
||||
|
||||
- Applied source candidate to .project-docs/30-worklog/current-state.md under Integrated Through. No additional canonical changes required.
|
||||
@@ -36,7 +36,8 @@
|
||||
## Follow-ups
|
||||
|
||||
- 配套部署 Yuxi API/worker 与新版 MakeLore;已有智能体若仍为 40 步,需调整限制、保存并重新发布。旧失败运行不自动续跑,生产微信完整链路仍待验收;本次不声称解决旧 output_persistence_error。
|
||||
- 依据 skill 在最终交付时另行确认源任务工作区清理,分支与提交保留;未得到清理授权前保留目录。
|
||||
- 用户确认清理本次列出的源任务工作区。同任务恢复 check/start/status 通过,沿用已加载记忆与未变化的 peer 上下文;重新核对源为 clean、managed、ready,提交记录已写 Ready for Integration,最新源提交已合入实际主分支。仅调用官方 retire,保留分支及提交。
|
||||
- 清理受阻:官方 retire 的 Git 删除返回 Directory not empty。删除已部分执行,源目录仍留有文件,但 Git 工作树登记已不在列表中;分支和源提交重新回读完整。未绕过 retire 手动删除或修改悬空所有权登记;残留保留,需确认原生文件删除及官方 release-missing 恢复。此故障不影响已完成主分支合并。
|
||||
|
||||
## Promotion Candidates
|
||||
|
||||
|
||||
@@ -608,13 +608,17 @@ export class CloudAgentsModule {
|
||||
if ((url.protocol !== 'https:' && !(url.protocol === 'http:' && ['127.0.0.1', 'localhost', '[::1]'].includes(url.hostname)))
|
||||
|| url.username || url.password || url.search || url.hash
|
||||
|| value.scope !== 'makelore-agents' || value.token_type !== 'bearer'
|
||||
|| typeof value.expires_at !== 'number' || value.expires_at * 1000 <= Date.now()
|
||||
|| value.expires_at * 1000 > Date.now() + 300000) {
|
||||
|| typeof value.expires_at !== 'number' || !Number.isSafeInteger(value.expires_at)
|
||||
|| value.expires_at * 1000 <= Date.now()) {
|
||||
throw new CloudAgentsError(502, 'cloud_service_unavailable');
|
||||
}
|
||||
this.cached = {
|
||||
binding, accessToken: textField(value.access_token, 8192),
|
||||
apiBaseUrl: url.toString().replace(/\/+$/, ''), expiresAt: value.expires_at * 1000,
|
||||
apiBaseUrl: url.toString().replace(/\/+$/, ''),
|
||||
// The issuer and this computer have independent clocks. Cap local reuse
|
||||
// instead of rejecting a valid five-minute credential for slight skew.
|
||||
// Yuxi remains responsible for enforcing the credential's actual expiry.
|
||||
expiresAt: Math.min(value.expires_at * 1000, Date.now() + 300000),
|
||||
};
|
||||
return this.cached;
|
||||
}
|
||||
|
||||
@@ -44,6 +44,35 @@ beforeEach(() => { vi.clearAllMocks(); journalRecords.clear(); clearWorksSquareS
|
||||
afterEach(() => { instances.splice(0).forEach((module) => module.dispose()); clearWorksSquareSession(); vi.useRealTimers(); });
|
||||
|
||||
describe('Main cloud Agents boundary', () => {
|
||||
it('accepts a five-minute session from a clock one second ahead and caps local caching', async () => {
|
||||
vi.useFakeTimers();
|
||||
const now = Math.floor(Date.now() / 1000) * 1000;
|
||||
vi.setSystemTime(now);
|
||||
const transport = vi.fn(async (url: string) => url.endsWith('/session')
|
||||
? json({ access_token: 'yuxi-secret', token_type: 'bearer', scope: 'makelore-agents',
|
||||
expires_at: Math.floor(Date.now() / 1000) + 301, api_base_url: 'https://agents.example.test' })
|
||||
: json({ agents: [], next_cursor: null }));
|
||||
const module = moduleFor(transport);
|
||||
expect(await module.list()).toEqual({ agents: [], next_cursor: null });
|
||||
expect(transport.mock.calls.map(([url]) => new URL(url).pathname))
|
||||
.toEqual(['/api/cloud-agents/session', '/api/makelore/agents']);
|
||||
vi.setSystemTime(now + 294000);
|
||||
await module.list();
|
||||
expect(transport.mock.calls.filter(([url]) => url.endsWith('/session'))).toHaveLength(1);
|
||||
vi.setSystemTime(now + 295000);
|
||||
await module.list();
|
||||
expect(transport.mock.calls.filter(([url]) => url.endsWith('/session'))).toHaveLength(2);
|
||||
});
|
||||
|
||||
it.each([0, -1, 1e308])('rejects an expired or invalid session timestamp %s before calling Yuxi', async (expiresAt) => {
|
||||
const transport = vi.fn().mockResolvedValue(json({
|
||||
access_token: 'yuxi-secret', token_type: 'bearer', scope: 'makelore-agents',
|
||||
expires_at: expiresAt, api_base_url: 'https://agents.example.test',
|
||||
}));
|
||||
await expect(moduleFor(transport).list()).rejects.toMatchObject({ code: 'cloud_service_unavailable' });
|
||||
expect(transport).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('persists recovery in the real electron-store file and reloads it after replacing Main', async () => {
|
||||
const directory = await mkdtemp(join(tmpdir(), 'makelore-cloud-journal-'));
|
||||
try {
|
||||
|
||||
Reference in new issue
Block a user