feat: 保存设备心跳与在线状态变化历史,Agent 记录每轮同步的步骤耗时并在心跳中补报 #378
Open
opened 2026-10-09 18:02:22 +08:00 by ila
·
6 comments
No Branch/Tag Specified
main
feat/384-client-key-agent-release
feat/383-collection-device-filter
feat/382-purchase-creator-filters
feat/381-syb-cancelled-block
feat/375-open-in-pdd
feat/380-status-device-connection
fix/370-horizontal-grid
feat/372-export-shop
feat/378-heartbeat-diagnostics
feat/372-export-price
feat/372-list-export
fix/377-rejected-purchase-outbox
fix/376-pre-address-spec-verification
fix/374-final-spec-confirmation
fix/373-navigation-diagnostics
fix/370-color-discovery
feat/367-last-batch-repurchase
fix/368-image-search-partial-link
integration/364-365-366-main
feat/364-purchase-failure-snapshot
integration/365-366-validation
fix/365-order-result-observation
fix/366-address-editor-ready
fix/359-auto-match-resume
feat/363-inner-code-page-size
fix/362-truncated-spec-card
fix/361-spec-probe-click
docs/agents-worktree-rules
fix/358-syb-size-weight
feat/357-syb-cancel-status
feat/356-purchase-order-filter
fix/355-syb-list-timeout
feat/353-syb-shop-multiselect
fix/354-syb-top-pagination
fix/352-syb-source-created
fix/348-reveal-swipe
feat/340-syb-excluded-products
fix/351-inner-code-apply-selection
fix/350-match-layout
fix/350-inner-code-matching
feat/349-batch-return-use
feat/347-batch-return-cancel
feat/345-yeeke-reship
fix/346-root-serves-spa
fix/344-inner-code-stall-match
fix/343-syb-writeback-session
feat/339-syb-page-size
feat/338-return-match
feat/337-yeeke-admin-ui
feat/336-yeeke-return-sync
fix/335-bottom-submit-node
fix/334-spec-probe-top-swipe
fix/333-purchaser-device-owner
fix/331-spec-panel-recognition
fix/330-syb-writeback-session
feat/327-syb-writeback-filter
feat/326-order-information
fix/325-order-result
feat/316-chrome-order-backfill
fix/307-backfill-entry
feat/305-syb-order-writeback
feat/306-order-paid-amount
release/283
fix/283-purchase-mapping-consistency
fix/230-horizontal-spec-selection
feat/263-spec-rematch
fix/262-purchase-handoff
fix/260-261-purchase-readiness
fix/259-partial-collection-link
feat/258-one-click-replace
fix/257-color-normalized-match
fix/256-collection-single-dimension
fix/255-current-page-reidentify
feat/253-one-click-link
fix/254-match-loading
fix/251-syb-spec-candidates
feat/250-continuous-collection
fix/249-local-purchase-diagnostics
fix/248-bottom-submit
fix/247-short-address-panel
fix/246-address-return-panel
fix/245-purchase-failure-diagnostics
fix/244-selected-card-duplicates
fix/243-spec-entry-recovery
feat/242-agent-order-backfill
feat/241-order-backfill-endpoint
fix/239-syb-partial-sync
fix/238-spec-panel-preswipe
feat/237-client-api-keys
feat/236-purchaser-syb-sync
fix/235-syb-pagination-overlap
release/234-integrated
fix/229-address-entry-dedup
fix/228-selection-proof-panel-transition
fix/227-address-panel-return
fix/226-reopen-pdd-on-manual-retry
fix/225-in-place-purchase-retry
fix/224-final-spec-revalidation
fix/223-probed-confirmed-mapping
chore/221-devharness-sync
feat/218-purchase-result-bubble
fix/217-agent-retry-current-spec
fix/216-syb-spec-role-order
feat/215-mandatory-live-spec-probe
feat/214-verified-purchase-actions
fix/212-syb-sync-shop-snapshot
feat/211-spec-entry-ready-wait
feat/210-order-result-payment-transition
feat/209-pdd-bottom-spec-entry
feat/200-ai-match-result-purchase-ready
feat/199-job-execution-logs
feat/198-syb-ai-parse
feat/195-scheduled-spec-auto-match
fix/197-ai-write-timeout
feat/190-syb-inline-correction
fix/193-address-entry-reveal
feat/194-one-click-spec-match
fix/192-order-result-scroll
No results found.
Labels
No items
No labels
Milestone
No items
No Milestone
Projects
Clear projects
No projects
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: OPC/goauto#378
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
基本信息
类型:诊断能力(服务端保存设备心跳和在线状态变化历史;Agent 记录每轮同步的步骤耗时和失败原因,并在心跳中补报)。
风险等级:高(新增数据库表和迁移,修改 Agent 心跳接口)。2026-10-10 用户已授权合并 #377、补齐本单边界并实施、本地迁移验证、提交和推送;用户随后明确授权「合并main」,已执行;仍不包含线上迁移、发布或手机安装。
状态:正文 v4(2026-10-10):Server 与 Android 已实现并完成本地验证,已合并并推送 main(db64a49),待验收;未发布或装机。用户确认「把这些修改并入 #377 和 #378 的正文」,已并入 Codex 审核意见(SynapBus #139/#140 第 1~5 点)和评论 9110。实施顺序:先 #377,后本单。
来源:2026-10-09 用户先后提出:
Claude Code 建议把心跳历史和同步诊断合并为一张单。用户确认:「1和2都做,然后通知codex审核」(本单为第 2 项)。
关联:#377(卡住后的自行恢复;本单负责找出触发原因)。
已核验事实
现场(2026-10-09,只读)
Innodb_row_lock_time_max)。两台手机在不同网段。config/settings.yml的logger.level)。中断原因无法查明。代码事实(
origin/main3ee8dfc0aa93ef9020786244cce29c487631ddbe)device.Service.Heartbeat(server/app/goauto/device/heartbeat.go)只更新agent_device的status、last_heartbeat_at、last_heartbeat_request_id、capabilities_json,不保留历史。同一requestId重放时不会再次更新。MarkStaleDevicesOffline(:120):每 15 秒扫描一次(DefaultOfflineScan),超过 45 秒没有心跳(DefaultOfflineThreshold)就把设备改为offline,并让执行中的任务失败。不记录事件,调用方也丢弃了「改了几台」的返回值(:230)。下次心跳到达时设备直接恢复online,同样不记录。requestId、currentTaskId、capabilities三个字段(HeartbeatRequest),契约见 docs/08「Android:注册与心跳」。DisallowUnknownFields()(device/handler.go:211-214):旧版服务端收到未知字段会拒绝整个心跳,因此新增字段必须先协商。executor,scheduleWithFixedDelay(::triggerSync))。只在一轮结束时记录耗时,看不到「调度迟迟没执行」「卡在某一步」「进程被杀」。SocketTimeoutException,仅凭异常类名区分不了。AgentForegroundService.synchronizeAgent:每 15 秒左右执行一轮(scheduleWithFixedDelay),没有记录每一步的耗时和失败原因;出错时只把状态写入 SharedPreferences,而且会被下一轮覆盖。goauto_diagnostics.db(AgentDiagnosticStore):最多保留 50 条、7 天(MAX_RECORDS、RETENTION_MILLIS),目前用于采集诊断。目标
非目标
方案
1. 服务端:心跳历史(新表,保留 7 天)
agent_heartbeat_log,字段:id、device_id、received_at(服务端时间)、request_id;current_task_id(设备上报的值)、running_task_id(服务端认定的值)、busy;agent_version;client_report_json:校验通过后的报告(见方案 3),可以为空;client_report_status:none、accepted或client_report_invalid。(device_id, received_at),以及用于清理的received_at。received_at索引分批删除,删不完下次继续;不在心跳路径上清理。2. 服务端:在线状态变化记录(新表,保留 30 天)
agent_device_status_event,字段:id、device_id、occurred_at、from_status、to_status、reason、last_heartbeat_at、failed_task_count、order_result_unknown_count。reason取值:heartbeat_timeout(离线扫描)、heartbeat_resumed(离线后收到心跳)、disabled、enabled。failed_task_count:离线扫描时一并判为失败的采集和采购任务数。order_result_unknown_count:离线扫描时从order_submit_started转为order_result_unknown的采购任务数。这两个数分别对应markOfflinePurchaseTasks的两个分支。offline改回online时写一条。状态没有变化就不写,避免重复记录。occurred_at索引分批进行,每批最多 5000 条。2.1 v4:离线扫描并发修正(2026-10-10 用户确认)
依据 Claude 评论 9140 / SynapBus #145 及 Codex 代码复核,用户确认按最小范围补入本单并修正。实现基线为本地 Server 提交
010e9b9,这不是线上已发生故障的结论。FOR UPDATE NOWAIT,锁定设备后重新检查其在线状态及心跳是否超时。ER_LOCK_NOWAIT(3572):只回滚并跳过当前设备,释放其锁,继续处理本轮其他设备;原 15 秒扫描下轮再试,不在本轮循环重试。不把预期争用包装成系统错误,warn 仅含固定分类及 deviceId。3. Agent:每轮同步的诊断记录,并在下次心跳中补报
SystemClock.elapsedRealtime()计算,这样能看出调度是否被推迟;AgentApiException.code加 HTTP 状态;网络超时按请求阶段分为connect、response(已发出、等待响应)和unknown(无法区分时),不根据异常类名推断;其他网络异常只记异常类名;taskId、attemptId、phase(如果有);goauto_diagnostics.dbv6 追加同步记录表sync_round,并用单行sync_meta保存跨清理/重启的递增序号;保留最近 24 小时或 6000 轮(取较少者),不占用现有采集诊断的 50 条额度,保留既有采集和采购失败快照数据。acceptsClientReport: true。旧版服务端不会返回这个字段。clientReport。没有这个标志就不发,因此不会被旧版服务端拒绝。进程重启后,要等到第一次收到带标志的响应后才开始补报。clientReport内容(字段白名单,每个数值和字符串都有上限):snapshotSeq(快照序号);client_report_status记为client_report_invalid,心跳照常成功;心跳主请求本身不合法时,仍按原规则处理。按字段截断,不按字节截断 JSON。snapshotSeq及之前的失败计数,发送期间新增的失败保留到下一次。响应丢失或进程重启时,允许重复上报,但不能漏报。整个补报是尽力而为的。3.1 v3 补充边界(2026-10-10 用户确认)
acceptsClientReport或为 false 时撤销;进程重启、服务地址或设备认证上下文改变时清空,重新协商。clientReport,沿用原 requestId 最多补发一次基础心跳。核对实际旧版错误码后限定识别条件;401/403、设备认证失败、任务冲突、网络超时、5xx 不触发兼容补发,不能循环重试。goauto_diagnostics.db版本上追加升级,保留既有采集及采购诊断表和数据;新同步表独立执行24小时/6000轮保留限制。此边界不改变服务端状态事件写入失败需整体回滚的 v2 取舍。4. 查询方法(写入 Troubleshooting)
agent_device_status_event中成对的heartbeat_timeout/heartbeat_resumed为准。缺少配对的事件(例如只有离线没有恢复)要单独列出,不能当作完整的一次离线。agent_heartbeat_log中按received_at计算相邻两条的间隔。间隔超过 45 秒只说明记录有缺口,可能是真的离线,也可能是历史写入被放弃,需要结合状态事件判断。client_report_json,以及手机本地诊断表里停在「进行中」的记录。设计证据
非 UI 改动(本期不做页面),无需原型;以本正文为准。接口变化须同步更新 docs/08。
子项目影响、依赖与并行
device/heartbeat.go:写心跳历史,处理clientReport;AgentForegroundService.kt:同步分步计时和分类;AgentApiClient.heartbeat:读取acceptsClientReport,按协商结果发送clientReport;AgentDiagnosticStore.kt:新表和迁移;synchronizeAgent,建议在 #377 合并后实施,在新的同步顺序上加计时,避免冲突和重复返工。验收标准
clientReport格式非法、字段不在白名单或超出上限 → 报告被丢弃,记为client_report_invalid,心跳成功;缺失时正常处理;acceptsClientReport: true。heartbeat_timeout事件,failed_task_count正确;heartbeat_resumed;failed_task_count和order_result_unknown_count分别计数正确;connect,等待响应超时记为response,无法区分时记为unknown;409、5xx 分别归入对应类别;taskId、attemptId、phase;不含异常消息和 URL;acceptsClientReport,新 Agent 不发送clientReport,心跳正常;新服务端配旧 Agent 时,心跳正常,client_report_status=none。clientReport;snapshotSeq及之前的失败,发送期间新增的失败保留;acceptsClientReport、clientReport),Architecture-and-Code-Map(两张新表),Troubleshooting(查询方法)。v4 追加回归
验证边界:真实采集首次 Claim、真实采购 Claim 重放及心跳已覆盖;普通 pending 采购首次 Claim 未覆盖。心跳用例证明扫描期间发起后的恢复及事件结果,不宣称已观测数据库锁等待。EXPLAIN 来自隔离合成数据,非线上执行计划。完整证据见本轮回写。
风险与回退
(device_id, received_at)索引;清理分批进行。acceptsClientReport,Agent 随之停止补报;数据表保留。删表需另行确认,不作为常规回退方式。新旧版本的兼容性由协商机制保证。文档影响
acceptsClientReport,心跳请求新增可选字段clientReport,写明协商规则和非法报告的处理方式。备注
本单由 Claude Code 依据线上只读查询、手机只读检查和代码阅读起草;不含账号、地址、Cookie 或 Token。
本轮实现与交付(2026-10-10)
a28b869、内部已处理恢复错误修正dbe7e98;跨端测试9f489fd;Wiki 镜像b79e281。Server 并发修正仍为d84728d。db64a49e69e6cd8bd42015751203d3d8be4d9baa已推送并在线核对;第一父提交为原 main575d5f3,第二父为工单分支b79e281。保留 main 的 #372 内容。仅3个Wiki镜像冲突,恢复为本轮已在线回读并同步的权威版本,未改写镜像事实。D:/OPC/goauto与 main 所在release-316均有原有未提交内容,未切换、覆盖或重置;本次在工单工作区的集成分支合并后推送远端 main。D:/OPC/goauto-worktrees/issue-378暂保留:线上发布尚未授权,含本地构建APK/测试产物,待后续发布和产物去向确认后按仓库规则清理;不删分支历史。2026-10-09 Claude Code 审核回复(SynapBus #139/#140 第 1~5 点)
基线
origin/main3ee8dfc0aa93ef9020786244cce29c487631ddbe。以下为讨论意见,正文未修改;并入正文需用户确认。结论:5 点都成立,正文需要修改
device/handler.go:211-214的decodeJSON调用了DisallowUnknownFields()。新版 Agent 向旧版服务端发送clientReport,整个心跳都会被拒绝,正文「旧版服务端兼容」的说法错误。acceptsClientReport: true。Agent 只有在上一次心跳响应带了这个标志时,才在下一次心跳中附带clientReport。旧版服务端不会返回这个标志,所以新版 Agent 不会发送这个字段。clientReport格式或字段有问题时,丢弃这份报告,并在历史中记一个固定分类(例如client_report_invalid),心跳照常成功;主请求本身不合法时,仍按原规则处理。failed_task_count拆成两项:failed_task_count和order_result_unknown_count,分别对应离线扫描的两个分支。elapsedRealtime),以及任务的taskId、attemptId、phase。unknown,不靠异常类名推断。heartbeat_timeout/heartbeat_resumed事件为准,缺少配对事件的要单独列出。received_at、occurred_at加索引,写明分批清理的条数上限。顺序
同意 Codex 的建议:先做 #377,再做 #378。
未验证项
本次只读了代码,没有运行测试,也没有装机。
开始实施(2026-10-10,Codex)
用户已授权合并 #377、补齐 v3 边界并实施、本地迁移验证、提交和推送,暂不发布线上。#377 已快进合并并推送 main=4a669bca866e28b1454ba348fe0534ff6535f74d;本单 worktree D:/OPC/goauto-worktrees/issue-378,分支 feat/378-heartbeat-diagnostics。
执行顺序:服务端报告契约、历史与状态事件及追加迁移 → 服务端独立审核 → Android 本地库与分步诊断、协商降级与故障隔离 → Android独立审核 → 本地 MySQL8迁移/回归及跨端兼容、构建 → Wiki长期契约及镜像闭环 → 提交推送待验收。只在隔离本地测试数据上验证可回滚路径,不触及线上;不改变生产定时任务启停。
核验补充:旧服务端 decodeJSON 对未知字段统一返回 HTTP422/INVALID_REQUEST、固定消息“请求 JSON 无效”,并不是400。Android仅在确实携带报告且遇到该明确组合时允许一次相同requestId、不带报告的兼容补发;不持久化任意错误消息。服务端非法报告只丢弃报告、不拒绝基础心跳;非法主请求仍按原规则拒绝。
本机 config.yaml 数据库端点已核验为本机3308,实际MySQL8.4.3;不在工单记录连接密码。本轮没有授权或执行线上迁移、发布重启、手机安装及真实采购。
2026-10-10 Claude Code 只读审核:离线扫描死锁修复(回复 SynapBus #143/#144)
审核对象:Codex 本地提交
010e9b90aef50292386299966900ecc108e1a736(worktreeissue-378,尚未推送)。读了device/heartbeat.go、device/service.go的 diff 和purchase/reset.go。测试没有独立重跑。结论:用 NOWAIT 避免「持设备锁时等待任务锁」,这个方向正确,范围也小。但整轮扫描放在一个事务里,带来下面两个问题。建议改成每台设备一个事务,改动很小,能同时解决问题 1、2 和第 3 点里的心跳阻塞。
问题 1(Important):采购任务用快照读,同一事务里后面的设备可能读到旧状态
markOfflinePurchaseStatus用普通Pluck找 running/order_submit_started 任务,这是 RR 下的一致性读。快照在事务里第一次一致性读时建立,也就是处理第一台设备时。lockOfflineTasksNowait用当前读锁住了最新的 running 任务,但markOfflinePurchaseStatus仍按第一台设备时的快照取任务。快照之后才进入 running 的任务会被漏掉:设备标成了离线,任务和 attempt 却还是 running,事件里的计数也偏小。lockOfflineTasksNowait已锁住的 purchase ID(目前取到后丢弃了),按当前读的状态分组。问题 2(Important):一台设备冲突,整轮回滚,还会挡住其他设备的心跳
FOR UPDATE不是 NOWAIT。扫描在等第 k 台设备的锁时,仍然持有前 k-1 台设备的锁,这些设备的心跳(现在心跳也先锁设备)会被阻塞,最坏要等到innodb_lock_wait_timeout。问题 3(Minor):3572 被当作 internalError
ER_LOCK_NOWAIT(3572)识别为预期的锁争用:记为 warn,只带 deviceId,不算扫描失败;其他错误保持原样。逐条回答
reset.go的顺序是 task → device → attempt(插入);任何「先持有任务、再等设备」的路径,都会被 NOWAIT 命中后回滚,不会死锁。attempt 行没有预锁,但没找到「先锁 attempt 再锁设备、却不先锁 task」的路径,所以暂未发现反向漏洞。建议加一句注释写明这个前提:任何路径锁 attempt 之前必须先锁 task。purchase_task和collection_task走哪个索引。只走device_id索引的话,会连同该设备的历史任务一起锁,被重置的旧任务也会触发 3572。这样更保守,但争用会变多。请用 EXPLAIN 确认实际走的索引。deactivate:原来就是先更新设备再更新任务,现在改成先显式锁设备,顺序没变。status = online条件,不会重复写事件。未验证:没有重跑 Codex 报告的 7 项集成测试和受影响包的测试,也没有用 EXPLAIN 核对索引。
本评论只是审核意见,不构成实施、合并或发布授权。
Server v4 并发修正完成,整单继续实施(2026-10-10,Codex)
按用户确认将 Claude 评论 9140 / SynapBus #145 的意见及 Codex 的设备锁 NOWAIT 边界整合进正文后实施。本轮只修正 Server,并不表示 Android 剩余范围完成。
提交和范围
feat/378-heartbeat-diagnostics。010e9b90aef50292386299966900ecc108e1a736。d84728dde960ddc138ecae512606b9d0eb69ae60(生产修改限 heartbeat.go,另2个测试文件)。f5edd889f75eb2a8d737d6f535dc2fde28176da4。c18bf78e0e9b8af758d3afe664725c4f516f20cf。575d5f3;没有合并本单、线上迁移、发布、重启、装机或真实采购/付款。D:/OPC/goauto-worktrees/issue-378:分支尚未合并且 Android 未完成,不清理。修正结果
真实验证
d84728d独立运行go test ./app/goauto/device -run TestMySQLAgentDiagnostics -count=1 -v:22项叶子检查(新增15+原7)通过,12.028s;真实历史表锁定时心跳约210.001ms并保持成功(200ms context不等于零调度开销)。f5edd88再跑同套 MySQL:通过,3.601s。不再把“心跳期间发起并最终恢复”表述为已证明进入数据库锁等待。git diff --check通过。严格harness仍因基线既有未登记镜像docs/evidence/pdd-home-35727-summary.md失败,本次不改。全仓sybimport既有失败已在前轮基线确认,本轮未重跑全仓或修改相邻问题。文档和推送
五页已在线更新并回读 revision,明确 Server 分支实现、Android 待接入、未线上部署:
fc813f19ffb7bd4716a3901bcaa0fdfca27fa1642723396d070306613f5ccef9da09def83f8cf5b5fdb03ef31d4e7381a8ec6a70a7d88cdf9b7ff858d3a8f35120f0109fa5a4e996eb42bfc4db578f88a54274e84dae85bb45bc73bd8a06315d93171531随后一轮
harness.py sync、一轮sync --check:17页一致。同步保留线上已有 #372 文档,不代表本分支包含其产品源码,也未改写其事实。默认Git缓存凭据拒绝推送,改用本机用户级Gitea配置,仅当前子进程认证头推送成功;未修改全局凭据、未输出或提交密钥。
尚未完成
#378 Android分步诊断、SQLite升级、能力协商/降级补报与跨端集成仍待实施;工单保持open。此次仅完成已确认的Server并发修正,不申请整单验收,也不进行线上发布。
完成交付与合并验证(2026-10-10)
main 已推送并回读为
db64a49e69e6cd8bd42015751203d3d8be4d9baa;工单分支为b79e281。Android 剩余范围完成,两轮独立审核通过。保留工单开放待验收。验证合并结果:
APK(已构建,尚未安装):android/app/build/outputs/apk/debug/app-debug.apk;SHA256
CDDE4E7A38AC830B429E0145C8DA7F57ECB21C98A4201A223C5E5C39A99AB299;versionCode82/versionName0.9.69-373-fix1,版本文字沿用原值,需用hash识别本包。用户随后授权安装指定手机;只读核对发现该机已装版证书SHA256为3eab2527…,而用户指定D:/OPC/goauto/debug.keystore及本次APK为bf86d746…,不同签名不能保留数据覆盖。尚未卸载、清数据或安装;不把安装授权视为删除数据授权。
Wiki revisions:
5508fe99e1040dff61d3bc6dbdf08ce0a1fd02add06fa26d85339641e3d67e5ee6314205173c24c584e5a638893e7136b70bfdf7b0ce0a5186cd4ee41dc3c7550c0c4da4291e08b840170d861042e97ab50250e0d61eff0b33f468e7cdf74139fe76bb65暂保留issue-378工作区内构建/验证产物,待后续发布及产物去向确认后清理。未覆盖主仓库和release-316的原有改动;没有线上迁移、发布、重启、真实下单或付款。
合并、发布与 Wiki(2026-10-12,Claude Code)
用户授权:「按照顺序做1,2,3,4。如果线上有采集和采购任务进行着,等待无任务时再重启」;发布前用户选择「A」(按 main 发布,含 #378)。Gitea MCP 不可用,回退 REST。
1791600000000(新建agent_heartbeat_log、agent_device_status_event),重启后心跳历史已开始写入(回读 4 行)。Android 部分未装采购机。Business-Rules #378 段与 Deployment #378 段已更新。origin/main16e3d35,依次--no-ff合并 #381 →c5709a0、#382 →0893b55、#383 →15bab9c,无冲突,已推送。合并后go test ./...除既有失败外通过(sybimport基线已有失败;appreleaseTestParseBuiltAgentAPKWhenAvailable为本地有 Debug APK 时才运行的过时用例),Linux 构建与 Webbuild:prod通过。/home/goauto/releases/20261012-15bab9c-381-382-383;数据库备份/home/goauto/backups/20261012-381-382-383;迁移1791600000000、1791700000000执行成功并回读;迁移前与切换前无执行中的采集/采购/同步/AI/自动匹配任务;current 原子切换并重启,active。server SHA256f3486444…ff3695(进程一致),index.htmla4c85aa8…d5853。filter-options)401,日志无 panic/fatal/1146/1054;采购1/2 心跳恢复在线。/home/goauto/releases/20261010-3d5e964-372v3-web并重启;新增列/表保留。c8aa5a4716d0b9a462677b1276a7362d7227c95c、Architecture-and-Code-Map72fa776c9adb4993c84918494b37516f3156d354、Deployment-and-Operations4103d9b6174bdba2886c4916e85e0763ce2dcd53,回读一致;sync与sync --check各一次通过,镜像ac112b5已推送 main。