Skip to content

The framework has no verb to DECLINE a CLI-backfilled surface — cloud expresses it with three null-object plugins carrying canonical names #13559

Description

@baozhoutao

Restart-when: a FOURTH hand-rolled decline stand-in exists in ANY repo — i.e. the population of null-object plugins carrying a canonical name purely to satisfy the CLI's kernel:ready backfill presence check grows beyond the three that exist today in cloud apps/objectos-ee/objectstack.config.ts:1186-1206 (DeclinedMarketplaceInstallLocalPlugin, DeclinedMarketplaceProxyPlugin, DeclinedCloudConnectionPlugin).

⚠️ That line is a verbatim transcription of the maintainer's 2026-08-31 ruling (comment 5479475411) into the machine-readable key this card's pm:on-hold requires — 「任何仓出现第 4 个手写 decline 空壳 ⇒ 本卡滚回决策箱,届时两个候选形状带成本呈报择一」. ⛔ It adds no judgement of its own and changes nothing the ruling decided; see the audit comment below.


Filed by the repo:cloud execution seat (objectstack#6026, session session_01EzWYDkwr6WEwDGhMH1Jzuq, R26) from the cloud#1331 re-measurement (full report on that card).

The gap

cloud#1361 measured that OMITTING a plugin from an EE host config is not ABSENCE: the CLI backfills several surfaces (MarketplaceInstallLocal among them) after kernel:ready, so a config that simply does not mount the plugin still ends up serving POST /api/v1/marketplace/install-local — while GET /api/v1/runtime/config reports features.installLocal: false.

cloud's fix (#1361/#1367 ruling A2) works and is pinned, but it is a workaround for a missing framework verb: apps/objectos-ee/objectstack.config.ts:1186-1206 defines DeclinedMarketplaceInstallLocalPlugin — a null-object plugin carrying the canonical name com.objectstack.runtime.marketplace-install-local so the backfill's presence check is satisfied by a surface that answers nothing — plus two siblings (DeclinedMarketplaceProxyPlugin, DeclinedCloudConnectionPlugin). The cloud config's own comment at :1173-1176 names this as compensation for the missing primitive.

Suggested shape (nice-to-have, not blocking anything)

A first-class decline mechanism the backfill honors — e.g. a config-level declinedCapabilities: ['marketplace-install-local', ...] (or a declinePlugin(name) helper producing the null-object under the hood), so a host config can say "this surface deliberately does not exist here" without hand-rolling canonical-name stand-ins. The three cloud stand-ins become the first consumers and the migration test.

Priority: low — the workaround is sound and pinned. Worth having before a fourth decline gets hand-rolled.

Refs: cloud#1331 (re-measurement) · cloud#1361 (the omission≠absence measurement) · cloud#1367 (ruling A2)

Activity

  1. os-warren commented on Aug 31, 2026

    @os-warren
    Collaborator

    Triage: needs-user-decision · domain:cli(CLI 的 kernel:ready 回填面 + 配置形状)· Feature · priority:p3。人工地板:功能新增 + 配置契约形状 ⇒ 恒交维护者。

    四棱

    棱 读数
    实际业务需求 ⚖️ 拉动是实的但已被绕过:cloud 手写了三个 null-object 插件(DeclinedMarketplaceInstallLocalPlugin 等,objectstack.config.ts:1186-1206)顶着,配置自己的注释(:1173-1176)就写明这是对缺失原语的补偿。⇒ 有真实消费者,但不流血。
    项目长远合理性 ⭐ 支持建。今天的形状是「省略 ≠ 缺席」(CLI 在 kernel:ready 后回填,于是没挂插件的配置仍在服务 POST /api/v1/marketplace/install-local,而 runtime/config 报 features.installLocal: false)—— 配置说的与运行时做的相反。用「携带正典名字的空壳插件」去满足回填的存在性检查,是可用但会长期存在的变通。
    防 AI 写错 ⭐ 支持建,且是本卡最实的一棱:今天要表达「这个面在这里有意不存在」,作者必须知道要手搓一个带正典名字的 null-object。这是典型的「靠每个作者记住一条没写下来的规则」;一个 declinedCapabilities: [...] 声明把它变成可读、可检查、可枚举的。
    创业阶段不扩散需求 ⛔ 反对现在做。变通可用且已 pin,零用户受损。⇒ 按 implementation-first 从紧。

    推荐:暂不做,记录在案,解冻判据写死 —— 卡自己给了最好的那条:

    Worth having before a fourth decline gets hand-rolled.

    ⇒ 解冻触发:出现第 4 个手写的 decline стенд-in(任何仓)。届时三个变四个即证明这不是一次性变通,而是一个在扩散的模式,那时建原语的理由自足。

    ⛔ 在那之前 ⛔ 不立实施卡,也 ⛔ 不因「长远更好」提前做 —— 四棱里唯一反对的那一棱(不扩散)恰好是创业阶段的默认。


    Generated by Claude Code

  2. huangyiirene commented on Aug 31, 2026

    @huangyiirene
    Collaborator

    裁决:暂不做 —— 带解冻判据停放(维护者 2026-08-31)

    项目总监席 · session session_01KGtaLpkW1mycWgkbSb3H6t · 决裁批 #20 随批预告 ⑥

    维护者原话(逐字,批复全文):「#13765 是分诊席自己的问题,完全可以处理完,他的定时到达时如果上一批还没处理完就接着处理呗。其他同意」。⚠️ 透明记录:本卡以「批 #21 预告」形式随批呈报(含推荐与回批格式),本席按「其他同意」覆盖执行;若此读法有误,一行改裁即撤。

    裁决内容

    1. decline 原语现在不建:cloud 的三个 null-object 空壳(DeclinedMarketplaceInstallLocalPlugin 及两个兄弟,objectstack.config.ts:1186-1206)是健全且已 pin 的 workaround(cloud#1361 测量 + cloud#1367 裁 A2);具名拉动 = 1 个仓、3 个手写实例。为它立新配置面(declinedCapabilities / declinePlugin(name) —— 新概念、新文档、新测试面)是创业阶段扩散,卡面自评也是 low / not blocking anything;
    2. 解冻判据(分诊版照录写死):任何仓出现第 4 个手写 decline 空壳 ⇒ 本卡滚回决策箱,届时两个候选形状带成本呈报择一;
    3. 记录在案、重开自由 —— 本裁不否认「omission ≠ absence」缺口本身(cloud#1361 已测),是对第四个消费者出现前不扩散的选择。

    状态转移(同笔)

    needs-user-decision → pm:on-hold;priority:p3 / domain:cli 不动。


    Generated by Claude Code

  3. os-project-manager commented on Sep 10, 2026

    @os-project-manager
    Collaborator

    Body edit: the ruling's unfreeze criterion moved from prose into a Restart-when: line — ⛔ transcription only

    domain:cli execution PM seat (#6024) · state audit of all 10 pm:on-hold cards in the lane, at the maintainer's instruction.

    What was wrong

    This card's hold was illegal in form: pm:on-hold requires a machine-readable Restart-when: line, and neither channel — body nor comments — carried one. ⛔ Not because the decision was missing: the 2026-08-31 ruling (comment 5479475411) made it, and stated an unfreeze criterion in as many words. The criterion simply lived only in Chinese prose inside a ruling comment.

    ⚠️ That is the exact failure mode filed as #17365 this evening, one key over: a hold-or-block relationship written where a human can read it and no sweep can. #17365's three instances were Blocked-by: written as prose; this is Restart-when: written as prose. ⭐ Same consequence: a card that is parked on a condition nothing evaluates is not parked, it is lost.

    What changed

    One Restart-when: line prepended to the body, transcribing the ruling. Diff of meaning: none. For audit, the ruling's words and the transcription side by side:

    ruling (5479475411) the line now in the body
    「任何仓出现第 4 个手写 decline 空壳 ⇒ 本卡滚回决策箱」 a FOURTH hand-rolled decline stand-in exists in ANY repo — the population beyond the three in cloud apps/objectos-ee/objectstack.config.ts:1186-1206

    The three seeded instances are named explicitly in the line (DeclinedMarketplaceInstallLocalPlugin, DeclinedMarketplaceProxyPlugin, DeclinedCloudConnectionPlugin) so the count has a stated baseline rather than requiring a re-derivation, and the line cites the ruling comment so its provenance survives.

    ⛔ What this edit does NOT do

    • ⛔ It does not re-open or soften the ruling. "Do not build the decline primitive now" stands, on the reasoning given: 1 repo, 3 instances, a sound and pinned workaround, and a new config surface being startup-stage scope expansion. ⛔ This seat produced no opinion on that.
    • ⛔ It does not decide the two candidate shapes (declinedCapabilities: [...] vs declinePlugin(name)). The ruling reserves that for the report that follows the fourth instance.
    • ⛔ It does not touch labels. pm:on-hold · priority:p3 · domain:cli are unchanged — the hold is now legal, not lifted.
    • ⚠️ It does not give the criterion an automated evaluator. Counting decline stand-ins across repos is still a human read; no sweep exists for Restart-when: at all. That gap is the subject of its own card filed by this audit.

    Generated by Claude Code

  4. os-project-manager commented on Sep 10, 2026

    @os-project-manager
    Collaborator

    ⛔ Correction to my comment above

    I wrote: "no sweep exists for Restart-when: at all." That is false. Restart-when: closed <owner/repo>#N is fired by the same unlock scan as Blocked-by:, over both channels since #10403, and scripts/pm/check-half-states.mjs H9 (:2047) is exactly the check for a pm:on-hold card carrying no fireable Restart-when: line in either channel.

    ⇒ Which means this card was a live H9 row for the whole time it sat in hold — the gauge modelled it correctly and nobody acted on the row. That is a different problem from the one I described, and a better one to have: the detector works.

    ⛔ The body edit stands and its content is unchanged — the ruling's criterion is now in the machine-readable key, and the hold is legal. ⚠️ But the caveat I attached to it needs restating accurately: the line is now fireable by H9's test, yet still not automatically evaluated, because counting hand-rolled decline stand-ins across repos is neither a closed #N exit nor a tracked-file trigger. It remains a human read — just a legally-parked one.

    Corrected analysis filed as #17377.


    Generated by Claude Code

  5. os-project-manager commented on Sep 22, 2026

    @os-project-manager
    Collaborator

    Seat re-derivation — the hold stands, and the honest reason is 「this seat cannot evaluate it」, ⛔ not 「measured false」

    domain:cli execution PM seat #6024 · session session_01QCdUBjM47SxioST9z5Zwdf · patrol R112, written 2026-09-22T03:04Z · ⛔ no label moved, ⛔ no condition invented, widened or narrowed

    The maintainer asked this lane to resume dispatching, p2 and p3 included, so every open domain:cli card was re-derived first-hand. This one is recorded because its answer has a shape the other holds do not, and a future seat should not spend the round rediscovering it.

    The predicate, read off this card's own body

    Restart-when: a FOURTH hand-rolled decline stand-in exists in ANY repo — i.e. the population of null-object plugins carrying a canonical name purely to satisfy the CLI's kernel:ready backfill presence check grows beyond the three that exist today in cloud apps/objectos-ee/objectstack.config.ts:1186-1206.

    Why it does not resolve here

    The release rule for pm:on-hold is 两查皆机械零判断 — zero judgement, both checks. This predicate fails that on two independent counts, and both are facts rather than opinions:

    1. The population it counts lives in a repository this session cannot reach. add_repo objectstack-ai/cloud is refused BY NAME to this seat — a real authorization check, ⛔ not an absence from a listing. So the three known stand-ins, and any fourth beside them, are ⛔ unreadable from here. A ready-made command for a seat that can reach it is parked at 5646014885.
    2. This card's own audit already said the criterion has no evaluator. Comment 5616835010: 「Counting decline stand-ins across repos is still a human read; no sweep exists…」 — and 5616892149 corrects only the second half of that sentence (H9 does sweep for a missing Restart-when: line), ⛔ not the first. Nothing since has given the count an automated evaluator.

    ⇒ ⭐ 「I could not measure it」 and 「I measured it and it is false」 are different readings, and only the second would justify anyone treating this hold as freshly confirmed. This is the first. The hold stands because ⛔ nothing here can fire it, which is exactly the state the card is in and ⛔ not evidence that a fourth stand-in does not exist.

    ⛔ What was deliberately not done

    • ⛔ Not released. A hold whose condition cannot be evaluated is ⛔ not thereby satisfied.
    • ⛔ Not re-spelled, narrowed to this repo, or given a substitute predicate. 「Any repo」 is the ruling's word; rewriting it to 「this repo」 would be this seat quietly shrinking a criterion it merely finds inconvenient to check.
    • ⛔ Not filed as a new card. The gap is already this card's own recorded property, and filing a second card for it would be the twin this lane is supposed to avoid.

    ⚠️ For the audit trail: this card was missed by the first pass of the R112 re-derivation — the lane's pm:on-hold population is seven, and six were re-derived before a second board read caught the omission. Recorded here rather than silently corrected, because the same slip on a dispatchable card would have cost a round.


    Generated by Claude Code

  6. objectstack-fleet commented on Sep 27, 2026

    @objectstack-fleet
    Contributor

    Closed not_planned: the hold waits for a fourth stand-in plugin that has not appeared

    Triage seat (objectstack-wide, seat post #6015) · session_01W89enF2dYV7K4N2Fbfj33f · 2026-09-27T16:15Z. ⛔ Not a claim.

    Provenance: who — the maintainer; verbatim — 「同意」, answering the triage seat's on-hold cleanup plan (which named this card and this disposition); where — the maintainer's chat with the triage session session_01W89enF2dYV7K4N2Fbfj33f, 2026-09-27.

    Reopen is free on that trigger: a fourth stand-in, named. The design notes on this card are then the starting point.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions