Replies: 1 comment
|
Three readings of published artifacts, about the guardrails in this proposal. Two are about what is already on the wire; the third is about where a release-level diff has to be taken to answer the question it is meant to answer. 1. The byte bound has landed on one field; the request body still has none
Two details differ from that item's wording. The bound is on the contributed field's own bytes, not on the composed request body, which still has no bound of its own. And the events taken are the oldest run rather than the most recent N: accumulation starts at The third bullet of that item is not addressed in rc.2: activation is still 2. On the three P2 items: one is closer than it looks, two are absentI read both halves of that path — the adapter ( Budget, per field and total: absent on both sides. The registry prepares every registered field in parallel and clones and freezes the values ( This is worth separating from item 1. The bound that exists today is a provider bounding its own field. The registry admits exactly one provider per field name and imposes no size contract, so a second auxiliary field is not constrained by anything the first one did. Degrade, then re-send without the field: the mechanism exists, the trigger does not. Circuit breaker, durable marker, surface: absent. Neither package mentions a breaker or a blocked state, and the only trace left when a field is dropped is a For completeness on the classification item: the branch that maps 400 and 413 to 3. A release-level diff has to be taken against published artifactsThe third guardrail's example is that release notes could not tell a user "this upgrade will start uploading your entire session history". The tree can be read for that; the tree is not where the answer lives. One case from the published set of
Between those dates master and the newest installable artifact disagree — 3 against 2 — so a diff keyed on merge dates reports a change as in effect up to six days before any user can receive it. The same holds for "which version first contains X": only a per-version sweep of published artifacts answers it, because the tree does not express which versions are reachable by install. The version a default install resolves to is a second input that a tree diff has no view of at all. Boundary: I read published tarballs and registry metadata on 2026-09-25 and executed nothing. The CI-fixture and wire-invariant parts of that guardrail are not verifiable from outside a checkout. I have not re-opened the threads in the prior-art table. Line numbers are from the rc.2 tarballs named above; the constant history is from npm's published version list for Authorship note: the readings above were taken by me against published npm artifact tarballs and registry metadata; drafting assisted by AI; verification and publication by me. I have no engineering background — if any technical claim reads wrong, please call it out; I will re-verify against the toolchain and correct. Reported by the OfferKuai Team — Founder: Zhaofeng (Yaming). Website: https://www.offerkuai.com/ | Contact: contact@offerkuai.com 中文版三条都是对已发布产物的读法,针对提案里的三条护栏。前两条讲"线上到底已经做到了什么",第三条讲"要回答发布级 diff 想回答的那个问题,diff 该取在什么地方"。 1. 字节界已经落在一个字段上;请求体仍然没有
有两处细节与那一项的措辞不同。这个界是贡献字段自身的字节,不是组合后的请求体 —— 请求体本身仍然没有界。取的事件是最旧的一段连续前缀,不是最近 N 条:累加从 那一项的第三条在 rc.2 里没有被回应:激活仍是 2. 关于 P2 的三项:一项比看起来更近,两项不在这条路径的两半我都读了 —— 适配器 预算(逐字段与总量):两侧都没有。 登记处把每个已注册字段并行准备、把值克隆并冻结( 这一点要与第 1 条分开看:今天存在的界,是提供方给自己那个字段加的界。登记处对每个字段名只接纳一个提供方,且不施加任何尺寸契约 —— 所以第二个辅助字段不受前一个做过什么的约束。 降级 / 去掉字段重发:机制已在,触发条件不在。 断路器 / 持久标记 / 面向用户的提示:都没有。 两个包里都没有断路器或"被阻挡"状态的表述;字段被去掉时留下的唯一痕迹,是序列化失败路径上的一条 补一句分类那条的现状:把 400 与 413 映到 3. 发布级 diff 必须以已发布 artifact 为对象第三条护栏举的例子是:release notes 说不出"这次升级会开始上传你的整份会话历史"。树是可以读的,但答案不在树里。
在这两个日期之间,master 与最新可安装 artifact 不一致(3 对 2),⇒ 按 merge 日期取 diff,会把一项变化报成"已生效",最多比任何用户能拿到它早六天。"哪个版本最先包含 X"是同一个问题:只有逐版本扫已发布产物能回答,因为树无法表达哪些版本可被安装到。而"默认安装会解析到哪个版本"是树 diff 根本看不到的第二个输入。 边界:以上读于 2026-09-25,取自已发布 tarball 与登记处元数据,未执行任何代码。第三条护栏里的 CI fixture 与 wire invariant 两部分,从仓库外不可核实。prior-art 表里的各条线索我没有逐条打开。行号取自上面点名的 rc.2 tarball;常量沿革取自 npm 上 声明:上列读数由我本人针对已发布 npm 产物 tarball 与登记处元数据完成;文稿撰写由 AI 辅助;核验与发布由我本人负责。我没有工程背景 —— 若任何技术表述有误,请直接指出,我会对照工具链重新核实并更正。我们是插件作者、不是维护者,本文不陈述任何官方政策。 本报告由 OfferKuai(Offer快)团队提交 —— 创始人:Zhaofeng(Yaming)。官网:https://www.offerkuai.com/ | 联系:contact@offerkuai.com |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Context
Follow-up to the repeated reports of large sessions getting permanently stuck on HTTP 413 at the official DeepSeek API once the session-log upload became default-on (see the prior-art table below).
Stripped of its specifics, that bug is an instance of a general pattern that this codebase is structurally exposed to:
Nothing exotic is required: no third-party plugin, no unusual configuration. Every user who upgrades with a large enough session hits it. The same shape is reachable from other durable-state consumers (projection caches, storage domains, workspace registry, telemetry prefixes, plugin inventories) whenever a default flips.
This proposal asks for three guardrails. They are independent; P2 alone would have prevented the stuck state, and it is the smallest change.
P1 — Stateful activation contract (plugin level)
A plugin whose behavior depends on durable state written before it was active must declare and implement its cold-start contract, and the loader/review checklist must require it:
Nevents ormaxBytes, plus an explicittruncatedFrom/baselineSeqmarker telling the receiver that earlier content was intentionally omitted. "No watermark ⇒ send everything" must not be a legal implementation.…/baseline-established), so "this session has never uploaded" is distinguishable from "this session uploaded and is current".P2 — Auxiliary-field isolation (adapter level)
Registered auxiliary top-level fields (
ctx.deepseekLlmApiExtensionstoday, potentially others later) are metadata contributions to a model request. A metadata contribution must never be able to make the model request permanently unusable.…/delivery-blockedwith the reason and the offending size) and tell the user once — instead of the current behaviour, where the session silently 413s forever and only showsDeepSeek Messages request failed (413).P3 — Upgrade-path guardrails (release and CI level)
dsh --dump-configalready renders the composed profile; a companion mode (dsh upgrade-check --from <version>or--diff <dump>) should print, for the previous and current release: entries whose defaults changed, entries newly enabled, and entries that consume pre-existing durable state. This is exactly the check that was missing: the 0.1.7 release notes could not tell a user "this upgrade will start uploading your entire session history".enabled: falseoverlay).Prior art behind this proposal
The pattern is not hypothetical and not a single user's environment — the tracker already holds several independent reports of it, plus a code-level confirmation:
session-log-deepseek/src/index.ts:136INVALID_REQUEST, so the context-window recovery path never firesAdditional evidence contributed under #7658: a machine-verified default diff (0.1.5-rc.2
enabled: false→ 0.1.7-rc.1enabled: true), the never-established-watermark measurements, and a workaround verified end-to-end after a restart.Six weeks of independent reports, one confirmed mechanism: the case for the guardrails below is not a new feature request, it is a request to make an existing, repeatedly-hit class of failure impossible.
Suggested order of work
dsh-session-log-deepseekupgrade-check+ CI fixture + size invariant)Question for maintainers
Would you accept a PR for P2, and/or for the P3
upgrade-checkdiff mode? I can start with whichever fits your roadmap; a first cut of P2 (budget + one retry without auxiliary fields + a per-session blocked marker) looks self-contained insidedsh-llm-deepseek+ the extensions registry.All reactions