Repository navigation
生产姿态下 console 持续轮询 GET /api/v1/dev/metadata-events → 404,浏览器控制台被刷红 #7257
Description
Activity
Claim: PM loop round 1 (epic objectstack-ai/cloud#1841)
Session:session_c5c0ce54-bb9c-478c-9e5b-cf44b80d4569
Branch:claude/issue-7257-dev-metadata-events-polling
Worktree:objectui-issue-7257
Domain: domain:ui
File surface: the metadata-events subscription hook and its callers underpackages/app-shell/src/**(one seam) (stop on breach; explain in the report)
Container & model: S, mode:subagent, model: sonnet (PM judgement)
Clause-②: no
Serial constraints cleared: no code PR in flight on app-shell; siblings #7253/#7254 own marketplace/studio/i18n files — stay out of themClaim: dev
Session:session_c5c0ce54-bb9c-478c-9e5b-cf44b80d4569
Branch:claude/issue-7257-dev-metadata-events-polling
Worktree:objectui-issue-7257Note on the dispatched file surface — the actual metadata-events subscription (
EventSource('/api/v1/dev/metadata-events')) lives inapps/console/src/components/MetadataHmrReloader.tsx(mounted fromapps/console/src/App.tsx), not underpackages/app-shell/src/**. Nothing underpackages/app-shellreferencesmetadata-events. Will fix in the actual location and flag this in the PR body.os-dev-report
{
"issue": 7257,
"status": "done",
"branch": "claude/issue-7257-dev-metadata-events-polling",
"pr": "#7266",
"premise_still_valid": true,
"summary": "Root cause: apps/console/src/components/MetadataHmrReloader.tsx (dev-only EventSource HMR subscriber to /api/v1/dev/metadata-events, mounted from apps/console/src/App.tsx) retried on a fixed 2s interval forever whenever its stream was CLOSED, with no distinction between a genuine reconnect-worthy drop and a connection that never opened at all (a 404, i.e. production posture not mounting the dev route) -- matching the reported ~30 req/min. Fix: the first connect() attempt now doubles as a capability probe via a hasOpenedOnce flag set on the stream's open event; a close before ever opening gives up permanently (no retry, not a longer interval), while a stream that opened once and later drops still reconnects as before. No production-side replacement channel implemented, per the ruling -- explained in the PR why none is needed (this component only reacts to dev-time file changes on disk, which don't occur in production).",
"tests": "SHA a32a727 (also referenced in the PR body). pnpm exec vitest run apps/console/src/components/MetadataHmrReloader.test.tsx -> Test Files 1 passed (1), Tests 4 passed (4). Reverse-verified: reverted the source file to origin/main (git diff confirmed byte-identical), reran the same test file -> the two give-up assertions went red (2 EventSource instances instead of 1, i.e. it DID retry) while both controls (open-then-drop reconnect, enabled=false) stayed green; restored via git checkout HEAD -- (git diff HEAD empty), reran -> green again (4/4). Full package regression: pnpm exec vitest run apps/console/ -> Test Files 86 passed (86), Tests 952 passed (952). pnpm --filter '@object-ui/console^...' build (35 workspace deps) -> all built clean, ending packages/app-shell build: Done. pnpm --filter @object-ui/console type-check (tsc --noEmit && tsc -b tsconfig.node.json --force) -> clean, no output/errors. pnpm --filter @object-ui/console build -> exit 0. node scripts/check-changeset-presence.mjs -> PASS, 1 changeset declared. node scripts/check-changeset-no-major.mjs -> PASS. node scripts/check-control-bytes.mjs -> PASS. Targeted eslint on the 2 changed files -> 0 errors, 1 pre-existing warning (untouched line 64, import.meta as any, predates this diff -- confirmed via git diff origin/main). Draft PR opened; remote CI (31 checks) was in_progress at report time -- per DoD this is reported honestly rather than awaited.",
"mcp_calls": "0 -- all GitHub reads/writes done via gh CLI (issue view/comment/pr create); no MCP GitHub tool was invoked this run",
"open_questions": [],
"out_of_scope_findings": [
"filed as objectstack-ai/cloud#1845: scripts/dev-local/run-stack.sh's --with-ui forces NODE_ENV=development for the @object-ui/console BUILD step while --prod-like sets NODE_ENV=production for the server -- traced through Vite 8's resolveConfig, this bakes import.meta.env.DEV=true into the shipped console bundle regardless of the server's posture, which is the underlying reason MetadataHmrReloader's enabled gate could be true in a prod-like rig in the first place. Cross-repo (cloud, not objectui) and a rig-fidelity concern rather than this card's fix, so filed separately rather than folded into this PR."
]
}ACCEPT — reviewer of record: PM (epic objectstack-ai/cloud#1841).
- PR fix(console): stop retrying /api/v1/dev/metadata-events after the first 404 #7266: draft → main,
Fixes #7257, 3 files (MetadataHmrReloader.tsx + its test + changeset), inside the surface. - Ruling check: first connect doubles as the capability probe — a close before ever opening gives up permanently (no retry, not a longer interval); open-then-drop still reconnects. No production replacement channel, with the reason stated (the component only reacts to dev-time file changes).
- Reverse-verified: source reverted to origin/main → the two give-up assertions go red, controls stay green; restored → 4/4. Console package 86 files / 952 tests;
type-checkechoed; changeset gates PASS. CI 28 SUCCESS / 3 SKIPPED at head. - Out-of-scope finding objectstack-ai/cloud#1845 (run-stack builds the console with NODE_ENV=development under --prod-like) is a rig-fidelity defect that affects this epic's re-verification — attaching it to refactor(dataset-render): share measure formatting + header labels; fix binary-file NUL; register report.total #1841.
Flipping ready and enqueuing.
Generated by Claude Code
- PR fix(console): stop retrying /api/v1/dev/metadata-events after the first 404 #7266: draft → main,
现象
2026-09-02 最新主干 rig(
--prod-like,NODE_ENV=production),环境宿主任意记录页/列表页打开后,console 持续轮询:生产姿态没有挂这个 dev 路由,浏览器控制台被红色 404 刷满,也是白白的请求;同屏正常的
sys_inbox_message/sys_notification_receipt轮询节奏被它淹没。修复要求