Skip to content

fix(discovery): preserve final rescue and bill ready losers#1353

Merged
ding113 merged 4 commits into
ding113:integration/discovery-stack-20260723from
Brisbanehuang:codex/discovery-final-rescue-billing
Jul 23, 2026
Merged

fix(discovery): preserve final rescue and bill ready losers#1353
ding113 merged 4 commits into
ding113:integration/discovery-stack-20260723from
Brisbanehuang:codex/discovery-final-rescue-billing

Conversation

@Brisbanehuang

@Brisbanehuang Brisbanehuang commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Keep one primary fallback plus one final standby after the last Discovery round, bounded by the configured concurrency. Either lane may rescue the current request, and a final standby never creates or renews Sticky.
  • Reuse the existing billHedgeLosers switch for Discovery attempts that already produced a protocol-valid response. Billing requires natural EOF, a protocol completion marker, and explicit usage; SLA timeouts, failures, no-prefix attempts, deadlines, and client aborts are still cancelled without inferred cost.
  • Itemize Discovery winner and billed-loser usage/cost in the request details and merged summary. Matching is strict by provider ID plus attempt number so repeated attempts cannot inherit another attempt's cost.

Safety boundaries

  • Legacy Hedge behavior is unchanged.
  • Discovery loser draining is disabled when billHedgeLosers is off.
  • The final rescue lane never raises active upstreams above Discovery concurrency and is disabled when concurrency is 1.
  • Winner cost uses loser-aware atomic persistence so async loser accounting cannot be overwritten.
  • Rectifier retries inherit final-rescue no-Sticky eligibility.

Verification

  • 22 Discovery coordinator tests passed
  • 70 ProxyForwarder tests passed
  • 7 loopback lifecycle tests passed
  • 20 billing/finalizer/repository tests passed
  • 44 request-details UI tests passed
  • bun run typecheck
  • bun run format:check
  • bun run lint
  • bun run i18n:audit-messages-no-emoji:fail
  • bun run build

The repository-wide placeholder audit still reports its existing Japanese and Traditional Chinese same-as-zh-CN baseline; this PR adds no entry to that failure list.

Dependency

This is a stacked PR and depends on #1351. Until #1351 merges, the dev comparison also contains its parent observability commits.

Refs #1340

Migration ordering

Migration 0109_nice_shriek is owned by #1336. That PR must merge before #1349, #1351, and this PR. After #1336 lands, rebase the Discovery stack in order and regenerate the 0110/0111 Drizzle metadata against 0109 before marking this PR ready. Deploying 0110 or 0111 first would cause the older 0109 migration to be skipped by Drizzle's timestamp ordering.

Greptile Summary

This PR expands bounded Discovery recovery and accounting. The main changes are:

  • Keeps a final rescue attempt within the configured concurrency limit.
  • Drains and bills eligible Discovery losers with explicit usage and natural completion.
  • Preserves loser-aware winner cost updates during asynchronous accounting.
  • Adds per-attempt Discovery billing details to request logs.
  • Returns a stable validation code for invalid Discovery windows.

Confidence Score: 5/5

This looks safe to merge.

  • The final rescue path remains bounded and does not write Sticky.
  • Discovery loser billing requires a ready response, natural completion, a protocol completion marker, and explicit usage.
  • Winner and loser cost writes preserve the combined request total across either completion order.
  • No blocking issue remains in the updated code.

Important Files Changed

Filename Overview
src/app/v1/_lib/proxy/discovery-coordinator.ts Adds final rescue selection and keeps active attempts within the configured concurrency.
src/app/v1/_lib/proxy/forwarder.ts Adds final rescue propagation, loser draining, billing snapshots, and no-Sticky handling.
src/app/v1/_lib/proxy/response-handler.ts Requires explicit usage for Discovery loser billing and preserves loser-aware winner cost updates.
src/app/[locale]/dashboard/logs/_components/error-details-dialog/components/DiscoveryTraceView.tsx Displays winner and billed-loser cost and usage by provider and attempt number.
src/app/[locale]/dashboard/logs/_components/error-details-dialog/components/SummaryTab.tsx Adds Discovery winners and billed losers to the merged provider-racing billing table.

Reviews (2): Last reviewed commit: "Merge remote-tracking branch 'origin/int..." | Re-trigger Greptile

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

有界 Discovery 与协议判定

Layer / File(s) Summary
Discovery 状态机与流式协议校验
src/app/v1/_lib/proxy/discovery-coordinator.ts, src/app/v1/_lib/proxy/discovery-validity.ts, tests/unit/proxy/*
新增 Sticky、轮次竞争、fallback、final rescue、协议 ready/terminal/error 判定及对应测试。
配置校验与 rollout 文档
src/app/api/admin/system-config/route.ts, messages/*/settings/config.json, docs/streaming-discovery.md
新增 Discovery 窗口参数校验、系统配置持久化、错误文案及生命周期和降级规则文档。
流式 Discovery 转发
src/app/v1/_lib/proxy/forwarder.ts, tests/integration/proxy-hedge-lifecycle.test.ts, tests/unit/proxy/proxy-forwarder-hedge-first-byte.test.ts
接入候选竞争、Sticky 探测、轮次 SLA、最终救援、取消、fallback 和条件性 loser drain 计费。
结算、绑定与资源释放
src/app/v1/_lib/proxy/response-handler.ts, tests/unit/proxy/response-handler-exported-finalizers.test.ts
重构完成标记和 Discovery lease 结算,增加绑定门控、辅助绑定确认、provider 引用释放、路由追踪持久化及显式 usage 计费条件。
日志详情与多语言展示
src/app/[locale]/dashboard/logs/_components/error-details-dialog/components/*, messages/*/dashboard.json, src/app/[locale]/dashboard/logs/_components/error-details-dialog.test.tsx
新增 Discovery 路由追踪视图,展示尝试、状态、时间线、取消原因、赢家及计费信息,并补充多语言文案和 UI 测试。

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

Suggested reviewers: ding113

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.83% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed 标题简洁且准确概括了主要改动:保留最终救援并为可计费的 Discovery loser 计费。
Description check ✅ Passed 描述与本次变更高度相关,涵盖了 Discovery 救援、计费、界面展示、验证和迁移顺序。
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai
coderabbitai Bot requested a review from ding113 July 22, 2026 14:11

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
src/app/v1/_lib/proxy/discovery-validity.ts (1)

203-204: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

可复用模块级 TextEncoder 以减少流式热路径上的分配。

每次 push 处理字符串分片时都会 new TextEncoder(),而在发现阶段竞速的流式路径上 push 可能被高频调用。解码器已是实例级字段,编码器同样是无状态的,可提升为模块级常量复用。

♻️ 建议改动
+const sharedTextEncoder = new TextEncoder();
+
 export class DiscoveryValidityParser {
     this.bytesSeen +=
-      typeof chunk === "string" ? new TextEncoder().encode(chunk).byteLength : chunk.byteLength;
+      typeof chunk === "string" ? sharedTextEncoder.encode(chunk).byteLength : chunk.byteLength;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/v1/_lib/proxy/discovery-validity.ts` around lines 203 - 204, 在
discovery validity 模块中将 TextEncoder 提升为可复用的模块级常量,并更新处理字符串分片的 push 逻辑使用该实例;保留非字符串
chunk 的 byteLength 计算不变,避免每次调用 push 时重复创建编码器。
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/streaming-discovery.md`:
- Around line 37-39: 更新 docs/streaming-discovery.md 中关于 Discovery losers
的描述:说明已产出有效响应前缀且已就绪的失败者会复用 legacy bill_hedge_losers 进行后台读取、drain
和计费;仅未满足该条件的失败者才会被取消并释放 readers、agents 和 provider-session 引用。保持文档与
messages/en/settings/config.json 的 billHedgeLosersDesc 语义一致。

In `@drizzle/meta/_journal.json`:
- Around line 766-774: 补齐 drizzle journal 中缺失的 idx 109 条目,使迁移序号从 108 连续到
110;使用对应的 0109_* 迁移标识及其正确的 version、when 和 breakpoints 元数据,并保持现有条目顺序不变。

In `@src/app/api/admin/system-config/route.ts`:
- Around line 64-73: 统一 UpdateSystemSettingsSchema.parse 的 ZodError
处理与此处手动校验的失败响应:当 superRefine 触发 discovery window 校验失败时,也返回稳定的
DISCOVERY_WINDOW_INVALID_ERROR_CODE,并保持与手动校验一致的响应结构。更新相关 ZodError
分支,避免完整更新和部分更新产生不同错误格式。

---

Nitpick comments:
In `@src/app/v1/_lib/proxy/discovery-validity.ts`:
- Around line 203-204: 在 discovery validity 模块中将 TextEncoder
提升为可复用的模块级常量,并更新处理字符串分片的 push 逻辑使用该实例;保留非字符串 chunk 的 byteLength 计算不变,避免每次调用 push
时重复创建编码器。
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d1978617-9f3b-4b09-b31b-ca17fa4a63d3

📥 Commits

Reviewing files that changed from the base of the PR and between 30bdda8 and 20fa640.

📒 Files selected for processing (120)
  • .env.example
  • docs/streaming-discovery.md
  • drizzle/0110_daffy_rawhide_kid.sql
  • drizzle/0111_happy_mauler.sql
  • drizzle/meta/0110_snapshot.json
  • drizzle/meta/0111_snapshot.json
  • drizzle/meta/_journal.json
  • messages/en/dashboard.json
  • messages/en/settings/config.json
  • messages/ja/dashboard.json
  • messages/ja/settings/config.json
  • messages/ru/dashboard.json
  • messages/ru/settings/config.json
  • messages/zh-CN/dashboard.json
  • messages/zh-CN/settings/config.json
  • messages/zh-TW/dashboard.json
  • messages/zh-TW/settings/config.json
  • package.json
  • src/actions/system-config.ts
  • src/actions/usage-logs.ts
  • src/app/[locale]/dashboard/logs/_components/error-details-dialog.test.tsx
  • src/app/[locale]/dashboard/logs/_components/error-details-dialog/components/DiscoveryTraceView.tsx
  • src/app/[locale]/dashboard/logs/_components/error-details-dialog/components/LogicTraceTab.tsx
  • src/app/[locale]/dashboard/logs/_components/error-details-dialog/components/SummaryTab.tsx
  • src/app/[locale]/dashboard/logs/_components/error-details-dialog/components/index.ts
  • src/app/[locale]/dashboard/logs/_components/error-details-dialog/index.tsx
  • src/app/[locale]/dashboard/logs/_components/error-details-dialog/types.ts
  • src/app/[locale]/dashboard/logs/_components/provider-chain-popover.test.tsx
  • src/app/[locale]/dashboard/logs/_components/provider-chain-popover.tsx
  • src/app/[locale]/dashboard/logs/_components/usage-logs-table.test.tsx
  • src/app/[locale]/dashboard/logs/_components/usage-logs-table.tsx
  • src/app/[locale]/dashboard/logs/_components/virtualized-logs-table.test.tsx
  • src/app/[locale]/dashboard/logs/_components/virtualized-logs-table.tsx
  • src/app/[locale]/settings/config/_components/system-settings-form.tsx
  • src/app/[locale]/settings/config/page.tsx
  • src/app/api/admin/system-config/route.ts
  • src/app/api/v1/resources/system/handlers.ts
  • src/app/api/v1/resources/system/router.ts
  • src/app/v1/_lib/proxy/discovery-coordinator.ts
  • src/app/v1/_lib/proxy/discovery-validity.ts
  • src/app/v1/_lib/proxy/error-handler.ts
  • src/app/v1/_lib/proxy/forwarder.ts
  • src/app/v1/_lib/proxy/provider-selector.ts
  • src/app/v1/_lib/proxy/response-handler.ts
  • src/app/v1/_lib/proxy/session.ts
  • src/app/v1/_lib/proxy/stream-finalization.ts
  • src/drizzle/schema.ts
  • src/instrumentation.ts
  • src/lib/api-client/v1/openapi-types.gen.ts
  • src/lib/api/v1/_shared/error-envelope.ts
  • src/lib/api/v1/_shared/request-body.ts
  • src/lib/api/v1/schemas/system-config.ts
  • src/lib/config/env.schema.ts
  • src/lib/config/system-settings-cache.ts
  • src/lib/ledger-backfill/trigger.sql
  • src/lib/lifecycle/shutdown.ts
  • src/lib/observability/discovery-metrics.ts
  • src/lib/redis/client.ts
  • src/lib/redis/live-chain-store.storage.test.ts
  • src/lib/redis/live-chain-store.test.ts
  • src/lib/redis/live-chain-store.ts
  • src/lib/redis/lua-scripts.ts
  • src/lib/redis/session-binding.ts
  • src/lib/session-manager.ts
  • src/lib/session-tracker.ts
  • src/lib/utils/provider-chain-display.test.ts
  • src/lib/utils/provider-chain-display.ts
  • src/lib/validation/discovery-settings.ts
  • src/lib/validation/schemas.ts
  • src/repository/_shared/transformers.ts
  • src/repository/message-write-buffer.ts
  • src/repository/message.ts
  • src/repository/routing-trace-outbox.ts
  • src/repository/routing-trace-persistence.ts
  • src/repository/system-config.ts
  • src/repository/usage-logs.ts
  • src/types/message.ts
  • src/types/routing-trace.ts
  • src/types/system-config.ts
  • tests/api/v1/system/system-config.test.ts
  • tests/configs/integration.config.ts
  • tests/configs/session-binding.config.ts
  • tests/integration/proxy-hedge-lifecycle.test.ts
  • tests/integration/session-binding-versioning-redis.test.ts
  • tests/unit/actions/system-config-save.test.ts
  • tests/unit/api/admin-system-config-route.test.ts
  • tests/unit/lib/redis/client.test.ts
  • tests/unit/lib/redis/live-chain-store.test.ts
  • tests/unit/lib/redis/session-binding.test.ts
  • tests/unit/lib/session-manager-binding-smart.test.ts
  • tests/unit/lib/session-manager-content-hash.test.ts
  • tests/unit/lib/session-manager-terminate-provider-sessions.test.ts
  • tests/unit/lib/session-manager-terminate-session.test.ts
  • tests/unit/lib/session-manager-versioned-binding.test.ts
  • tests/unit/lib/session-tracker-cleanup.test.ts
  • tests/unit/lib/shutdown.test.ts
  • tests/unit/proxy/discovery-coordinator.test.ts
  • tests/unit/proxy/discovery-validity.test.ts
  • tests/unit/proxy/error-handler-durable-persistence.test.ts
  • tests/unit/proxy/hedge-winner-dedup.test.ts
  • tests/unit/proxy/provider-selector-cross-type-model.test.ts
  • tests/unit/proxy/provider-selector-group-priority.test.ts
  • tests/unit/proxy/provider-selector-model-mismatch-binding.test.ts
  • tests/unit/proxy/proxy-forwarder-hedge-first-byte.test.ts
  • tests/unit/proxy/proxy-forwarder-provider-session-release.test.ts
  • tests/unit/proxy/response-handler-abort-listener-cleanup.test.ts
  • tests/unit/proxy/response-handler-client-abort-drain.test.ts
  • tests/unit/proxy/response-handler-endpoint-circuit-isolation.test.ts
  • tests/unit/proxy/response-handler-exported-finalizers.test.ts
  • tests/unit/proxy/response-handler-gemini-stream-passthrough-timeouts.test.ts
  • tests/unit/proxy/routing-trace.test.ts
  • tests/unit/proxy/terminal-outcome-contract.test.ts
  • tests/unit/repository/message-terminal-write-apis.test.ts
  • tests/unit/repository/message-write-buffer.test.ts
  • tests/unit/repository/routing-trace-outbox.test.ts
  • tests/unit/repository/system-config-degradation-ladder.test.ts
  • tests/unit/repository/system-config-update-missing-columns.test.ts
  • tests/unit/types/routing-trace.test.ts
  • tests/unit/usage-ledger/trigger.test.ts
  • tests/unit/validation/system-settings-discovery.test.ts

Comment thread docs/streaming-discovery.md Outdated
Comment thread drizzle/meta/_journal.json
Comment thread src/app/api/admin/system-config/route.ts
@Brisbanehuang
Brisbanehuang marked this pull request as ready for review July 22, 2026 14:43
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

Comment thread src/lib/redis/session-binding.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: de15e9c320

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +769 to +772
"idx": 110,
"version": "7",
"when": 1784571513591,
"tag": "0110_daffy_rawhide_kid",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Restore migration ordering before deployment

When this journal is applied on a database that has only migrations through 0108 (I checked this tree and drizzle/0109*.sql is absent), Drizzle Kit v0.x will record 0110's when as the newest applied migration; Drizzle's v0→v1 notes state that v0 only looked for local migrations newer than the last applied one, so the dependency's later-added 0109 migration would be silently skipped. Please include/rebase 0109 before these entries or regenerate 0110/0111 with later timestamps before merging.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

同意该阻断项。0109_nice_shriek 由 #1336 持有;PR 正文已写明 #1336 必须先于 #1349/#1351/#1353 合并。标记 Ready 不改变部署顺序:#1336 合并后,会依次 rebase Discovery 栈并基于 0109 重新生成 0110/0111 的 snapshot、journal 和时间戳,再运行迁移校验;完成前不会合并或部署本 PR。该线程暂不 resolve,保留为显式 merge guard。

@ding113
ding113 changed the base branch from dev to integration/discovery-stack-20260723 July 22, 2026 23:28
ding113 added 2 commits July 23, 2026 09:00
…0723' into agent/discovery-1353-on-integration

# Conflicts:
#	messages/en/dashboard.json
#	messages/ja/dashboard.json
#	messages/ru/dashboard.json
#	messages/zh-CN/dashboard.json
#	messages/zh-TW/dashboard.json
#	src/app/[locale]/dashboard/logs/_components/usage-logs-table.test.tsx
#	src/app/v1/_lib/proxy/forwarder.ts
#	tests/unit/proxy/response-handler-endpoint-circuit-isolation.test.ts
…0723' into agent/discovery-1353-on-integration

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/app/[locale]/dashboard/logs/_components/error-details-dialog.test.tsx (1)

1903-1995: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

修正不同 attempt 的 winner 成本断言

该用例声称旧 loser 不应关联到后续 winner,但 101:1$0.006 仍被用于将总成本 $0.015 推导为 winner 的 $0.009。这与“按 provider ID 和 attempt number 匹配成本”的 PR 约束冲突。请改为使用与 101:4 匹配的 loser 数据,或断言不受 101:1 成本影响的 winner 结果,并明确 costUsd 的总成本语义。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/`[locale]/dashboard/logs/_components/error-details-dialog.test.tsx
around lines 1903 - 1995, The test fixture in “does not attach an older loser
cost to a later winner from the same provider” uses an unmatched loser cost
while asserting a derived winner cost, conflicting with attempt-specific
matching. Update hedgeLosers to include cost data matching provider 101 and
attempt 4, or change the assertions to verify the winner result is unaffected by
the 101:1 cost; ensure the test explicitly reflects that costUsd represents the
total cost.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/app/`[locale]/dashboard/logs/_components/error-details-dialog.test.tsx:
- Around line 1903-1995: The test fixture in “does not attach an older loser
cost to a later winner from the same provider” uses an unmatched loser cost
while asserting a derived winner cost, conflicting with attempt-specific
matching. Update hedgeLosers to include cost data matching provider 101 and
attempt 4, or change the assertions to verify the winner result is unaffected by
the 101:1 cost; ensure the test explicitly reflects that costUsd represents the
total cost.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2dc95a1b-4d56-46da-a912-647e77511a3e

📥 Commits

Reviewing files that changed from the base of the PR and between de15e9c and 6a25fcc.

📒 Files selected for processing (11)
  • drizzle/meta/_journal.json
  • messages/en/dashboard.json
  • messages/ja/dashboard.json
  • messages/ru/dashboard.json
  • messages/zh-CN/dashboard.json
  • messages/zh-TW/dashboard.json
  • src/app/[locale]/dashboard/logs/_components/error-details-dialog.test.tsx
  • src/app/[locale]/dashboard/logs/_components/error-details-dialog/components/SummaryTab.tsx
  • src/app/v1/_lib/proxy/forwarder.ts
  • tests/integration/proxy-hedge-lifecycle.test.ts
  • tests/unit/proxy/proxy-forwarder-hedge-first-byte.test.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • messages/en/dashboard.json
  • src/app/[locale]/dashboard/logs/_components/error-details-dialog/components/SummaryTab.tsx
  • tests/unit/proxy/proxy-forwarder-hedge-first-byte.test.ts
  • src/app/v1/_lib/proxy/forwarder.ts

@ding113
ding113 merged commit 671870b into ding113:integration/discovery-stack-20260723 Jul 23, 2026
3 checks passed
@github-project-automation github-project-automation Bot moved this from Backlog to Done in Claude Code Hub Roadmap Jul 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants