Skip to content

Release v0.2.13+custom.001: upstream sync and Plus fixes - #117

Merged
LuckyKuang merged 52 commits into
mainfrom
sync/v0.2.13+custom.001
Oct 2, 2026
Merged

LuckyKuang merged 52 commits into
mainfrom
sync/v0.2.13+custom.001

Conversation

@LuckyKuang

@LuckyKuang LuckyKuang commented Oct 2, 2026 •

Copy link
Copy Markdown
Owner

Summary

Prepare Sub2API Plus v0.2.13+custom.001 on the official v0.2.13 baseline, including the v0.2.12 import. Preserve Plus billing, routing, outbound identity and ingress audit behavior.

  • Fix settlement after API-key deletion, support-view announcement popups, and global V3 status/event visibility.
  • Correct CN-provider group allowlist candidates and share the refreshed model catalog across frontend, backend and DeepSeek admission, retaining original upstream model names.
  • Include dependency security fixes, local deployment tooling and current documentation; align embedded version, Docker defaults and planned release mapping.

Verification

  • Focused backend and frontend regressions passed in Apple Containers during implementation.
  • Full official local matrix, including isolated PostgreSQL/Redis integration tests, passed in Apple Containers; the generated submit-pr proof binds the exact base and head.
  • Existing SQL migrations remain immutable; upstream forward migrations are preserved.
  • Existing outbound identity and ingress audit contracts are preserved.
  • No credentials, production configuration or user data are included.
  • Release notes cover compatibility, account/model limitations and the official v0.2.13 baseline.

Documentation and Release Impact

Provider/model, protocol, audit, monitor, support-view and deployment documentation describe current behavior. Release preparation synchronizes install/image/rollback examples; publication status is finalized through a separate PR after immutable Release verification.

aofee and others added 30 commits September 20, 2026 20:20
Replace the static priority number in the accounts table with a compact
stepper: hover reveals -/+ buttons, clicking the value allows typing
(Enter to save, Esc to cancel, arrow keys to nudge). Rapid clicks are
debounced into a single priority-only PUT, failures revert the value and
surface a toast, and the row is patched in place without a full reload.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
disabled:opacity-30 overrode opacity-0, so the decrement button stayed
faintly visible on every row already at the minimum. Style disabled
buttons via text colour instead, and raise idle icon contrast.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
POST /api/v1/payment/public/orders/verify is unauthenticated and still used
by PaymentResultView as a fallback, so keep it but cap it at 20 req/min per
client IP (fail-open on Redis errors) to make out_trade_no enumeration
impractical without affecting users mid-payment.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ient

The antigravity Gemini forward path returned the raw upstream Google error
body to end users, which can contain consumer project numbers, GCP project
IDs and service account emails. Return a Gemini-style error body with only
code/status and a scrubbed message; raw body stays in ops logging.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…okens

- Verification code attempts (register + notify email) are now reserved via
  an atomic Redis INCR (Lua) before comparing, so concurrent wrong guesses
  cannot exceed the 5-attempt cap.
- Password reset tokens are stored as SHA-256 hashes and consumed with an
  atomic Lua compare-and-delete, so a token can only be used once even under
  concurrent requests.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The warning said "Other errors will return 500", but custom error codes
only gate normal account-error handling (stop scheduling, rate-limit
marking). Request retry and account failover decide independently: on the
OpenAI-compatible gateway, unselected 403/5xx still fail over to another
account and only exhaust to 502; only some non-failover paths (for example
an ordinary 400) are rewritten to a generic 500. Reword zh/en to describe
what the setting actually does, including that an empty list applies no
filtering.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
修复 Grok 426 并对齐交互式 CLI 身份头
- 后台支付设置新增「充值赠送阶梯」(满 X 送 Y%,RECHARGE_BONUS_TIERS)与 Markdown 活动文案
  (RECHARGE_BONUS_NOTICE):阈值按用户输入的支付金额命中(取不超过金额的最大档),
  赠送按到账基数(输入 × 充值倍率)计算;严格校验写入、宽松解析读取,订阅订单不参与
- 下单时按当时配置计算赠送并落库:payment_orders 新增 bonus_amount 列(迁移 241),
  amount 仍为到账总额,到账/兑换码/退款逻辑不变;推广返利基数改为 amount - bonus_amount
- checkout-info 下发 recharge_bonus_tiers / recharge_bonus_notice;创建订单与订单查询响应带 bonus_amount
- 充值页:快捷金额按钮右上角「+N%」角标 + 第二行到账金额,金额卡顶部渲染活动文案,
  订单摘要新增赠送额度行并在有赠送时始终显示到账余额;订单列表/详情/支付结果/成功面板显示含赠送
- 后台新增 RechargeBonusTierEditor(行内校验重复/非法阈值,自动排序并显示区间预览)
- 补后端单测、契约测试与前端 vitest,zh/en 文案
- 新增全局模式开关 RECHARGE_BONUS_MODE(bonus / discount),接入支付配置、后台设置接口与 checkout-info
- 折扣模式:到账不变,实付基数按百分比打折(按币种精度取整),手续费 / 每日限额 / 渠道选实例沿用折后基数;
  百分比须 < 100,运行时 ≥ 100 按无优惠处理
- 充值页角标改为单行红色价签(赠金「+20%」/ 折扣「20% OFF」),第二行按模式显示到账或折后实付;
  摘要卡折扣模式显示优惠行,渠道限额校验改用折后实付
- 后台「充值优惠阶梯」拆为独立卡片:赠金 / 折扣切换、紧凑档位表格、区间预览、活动文案
- 补前后端单测与 zh/en 文案
- 新增 241 迁移:user_platform_quotas / composite_model_routes 的 CHECK 约束
  加入 typesafe。此前设置 typesafe 默认配额会让注册时的多行配额快照整体
  违约(fail-open 后新用户所有平台配额丢失),单用户配额与 Composite 路由保存 500。
- Prompt 审计新增 typesafe_systemone 协议提取(state + 各问题 instructions/
  criteria/选项标签,键排序保证哈希稳定);此前提取为空,阻断与异步审计均被放行。
  旧内容审核同样覆盖问题文本,且不再丢弃含 <system-reminder> 的 System One 文本。
- TypeSafe 分组及路由到 TypeSafe 的 Composite 请求访问 Messages / count_tokens /
  Chat Completions / Responses 时返回 404,避免以 x-api-key 打到错误上游路径并
  污染账号状态;TypeSafe 账号 base_url 为空时不再回退 api.anthropic.com。
- SystemOne 补在途余额预留、利润控制准入终检、wrapReleaseOnDone,失败切换改用
  共享 FailoverState(同账号重试 / 池模式 / 临时封禁)。
- 上游错误沿用共享账号错误策略:402/403、自定义错误码、临时不可调度规则生效,
  记录 ops 上游错误;400/422 仍不切换且永不改变账号状态。
- 账号测试改走原生 System One 探测,可用模型只返回 jev-latest;
  响应超限显式报错,响应 Content-Type 仅透传 JSON 类型。
- System One 校验拒绝重复键与大小写/Unicode 折叠变体键(请求顶层、
  questions、问题对象):encoding/json 大小写不敏感且取最后一个重复键,
  而原始 body 原样转发,此前 {"model":"x","MODEL":"jev-latest"} 可绕过
  jev-latest 限制、模型白名单与流式限制。
- Prompt 审计与旧审核同时收集对象键名、问题 ID 与未知扩展字段(不含规范
  字段名与已校验的 type),此前把内容放进键名即可完全绕过审计。
- 上游成功响应的 usage/model 宽松解码(浮点、数字字符串),避免上游已
  计费而网关整体 502 不记账;解码失败记录 response_error ops 事件。
- 上游 413 与 400/422 同视为请求错误:透传状态码、不切换、不改账号状态。
- TypeSafe base_url 末尾的 /v1 自动剥离,避免拼出 /v1/v1/systemone;
  /v1/systemone 改挂文本请求体上限。
- Composite 静态兜底模型列表、管理端候选列表恢复为不含 jev-latest;
  Codex 清单永不列出 TypeSafe 模型;TypeSafe 分组候选默认 jev-latest。
- 创建账号从 Grok 切到 TypeSafe 时重置为白名单模式;错误透传平台列表补 typesafe。
feat: add native TypeSafe Jev System One support
feat(payment): 充值优惠阶梯,支持赠金与折扣两种模式
…fy-hardening

fix(payment): 为匿名订单查询接口 /payment/public/orders/verify 增加 IP 限流
feat(keys): 支持按分组名称排序 API 密钥
…ize-upstream-error

fix(antigravity): 返回客户端前脱敏上游错误体,避免泄露账号池身份
…atomic

fix(email): 验证码尝试次数原子化 + 重置密码 token 哈希存储且原子单次消费
…s-warning-text

fix(frontend): correct custom error code warning and upgrade Axios
…-quick-adjust

feat(admin): inline quick-adjust stepper for account priority
kingsleydon and others added 22 commits October 2, 2026 10:45
The create form shows the upstream billing auto-probe toggle for every
API-key platform and enables it by default. TypeSafe was added as an
API-key platform but not to IsUpstreamBillingProbeIdentity, so creating a
TypeSafe account with the default form state fails with
400 UPSTREAM_BILLING_PROBE_ACCOUNT_INVALID ("account is not an API key
account").

TypeSafe accounts store credentials.api_key/base_url like every other
API-key platform, which is all the probe reads. Add TypeSafe to the probe
identity set, and add typesafe.ai to the official API domains so accounts
on the default https://api.typesafe.ai base URL record "unsupported"
without sending the key to a path that cannot exist, matching the other
official providers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs: add security policy with private vulnerability reporting
Merge official v0.2.12 (tag object cbe9966432317e6757b47f598a103d2132ec27db,
peeled 5106065) onto the integrated v0.2.11
tree; the merge base is exactly 96f4c11.

Plus adaptation:
- resolve 28 conflicts keeping Plus credential-owner identity precedence,
  the canonical two-engine audit extractor, session/quota semantics, the
  retired upstream billing probes and the local grok-build identity.
- rewrite upstream module paths in newly imported Go files to
  github.com/LuckyKuang/sub2api-plus.
- introduce upstream's two 241 migrations as the next free Plus prefixes
  (273_add_typesafe_platform.sql, 274_add_payment_order_bonus_amount.sql);
  the platform CHECK keeps the full Plus platform set plus typesafe, and the
  bonus column defaults to 0 for historical orders.
- regenerate Ent and Wire in the validation container (output is idempotent).
- declare the required build tags on newly imported Go tests.
- align the frontend platform-quota editor with the centralized platform
  catalog and fix upstream's stale settings.authSourceDefaults expectations
  (five -> six platforms after upstream added typesafe).
- normalize backend/go.mod and go.sum with go mod tidy.

Feature work carried by this sync:
- TypeSafe System One: canonical audit extraction shared by both engines
  (literal harness tags stay auditable), explicit platform identity mapping
  through the existing owner-preparation boundary, exact Jev reference
  pricing, usage snapshot before asynchronous submission, provider docs.
- Grok: compiled pin 1.0.45 from the frozen grok-build source (floor 1.0.41,
  identifier grok-shell, mode headless), Accept derived from the final
  serialized body, Content-Encoding reserved from generic overrides, and
  capability-negotiated zstd request compression with plain-JSON fallback.
- Email verification: generation-bound reserve plus atomic conditional
  consume and hashed single-use password-reset tokens.
- Recharge incentives: order snapshots, commission base excluding the free
  part, cumulative proportional refunds and the unified daily-limit basis.
- Antigravity upstream errors sanitized on every client return path.

The published embedded version 0.2.11+custom.002 is retained; release
preparation, tags and images remain a separate authorized step.

Refs: UPSTREAM.md, docs/UPSTREAM_V0_2_12_INTEGRATION.md
The npm package `xlsx` is abandoned at 0.18.5 and carries two high
advisories (CVE-2023-30533 prototype pollution, CVE-2024-22363 ReDoS)
with no patched npm release, so the previous risk acceptance in three
separate ledgers could never be resolved by a registry upgrade.

- vendor the official SheetJS CE 0.20.3 tarball as
  frontend/third-party/xlsx-0.20.3.tgz and depend on it with a file:
  specifier, keeping the `xlsx` module specifier so application code, the
  dynamic import and the existing Vitest mock are unchanged. SHA256SUMS
  records the size, sha256, sha512, source URL, version and fetch date.
- drop the exception from frontend/package.json (pnpm.auditConfig),
  .github/audit-exceptions.yml and SECURITY.md; the production audit now
  reports zero xlsx advisories (high: 2 -> 0).
- make tools/check_pnpm_audit_exceptions.py fail when an exception matches
  no reported advisory, add fixture tests, and keep the expiry path
  reachable now that ignoreCves no longer hides the advisories.
- replace the usage-export regression guard with a repository-wide
  write-only invariant plus ledger-consistency checks.
- copy frontend/third-party/ before the install layer in the
  frontend-builder stage and remove the stale frontend/audit.json
  (now gitignored).
- regenerate frontend/pnpm-lock.yaml with the pinned pnpm 9.15.9: the
  file: resolution replaces the seven 0.18.5 transitive packages.
… completes

When an API key with quota or rate limits was deleted while a request was
still in flight, the key counter update matched no rows and returned
ErrAPIKeyNotFound, rolling back the whole billing transaction including the
balance/subscription charge. Skip the key-scoped counters in that case and
keep settling the user and account side as usual.
`golangci-lint run ./...` reported
resetGrokRequestCompressionCapabilityCacheForTest as unused because the
unit-tagged test file that calls it is not part of the default lint build.
Move the test-only helper into grok_request_compression_test.go so
production code carries no test-only symbol. Behavior is unchanged:
go build, the focused compression tests and golangci-lint are all green.
fix(billing): settle usage when the API key is deleted before billing completes
…ng-probe

fix(billing): allow upstream billing probe for TypeSafe API-key accounts
The default Apple Builder allocation (2 CPU / 2 GiB) is killed with
`cannot allocate memory` (exit 137) during the frontend production build:
the Dockerfile runs `pnpm run build` with
NODE_OPTIONS=--max-old-space-size=3072 and vite needs more than 2 GiB.
Document the required allocation and the recovery commands in
deploy/APPLE_CONTAINER.md (Requirements and Disk Lifecycle), so a local
`container build` does not fail this way again. Raising the builder memory
is not a cache change: the builder keeps its layers and a killed build
simply resumes.
Remove completed integration and implementation drafts after preserving operational contracts. Keep the complete release table and correct v0.2.7+custom.001 to published.
Import settlement for deleted API keys and verify retry idempotency. Preserve the removed upstream billing probes, Plus release metadata, identity and ingress audit contracts. Keep security reporting on the Plus repository and update the integrated upstream baseline.
@LuckyKuang
LuckyKuang enabled auto-merge October 2, 2026 17:11
@LuckyKuang
LuckyKuang merged commit eef29a4 into main Oct 2, 2026
11 checks passed
@LuckyKuang
LuckyKuang deleted the sync/v0.2.13+custom.001 branch October 3, 2026 01:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants