Skip to content

make the body-dialect producer table come from a SCAN, not an enumeration — the first deliverable is the CRITERION, not another count #9871

Closed

Description

@os-tesla

Make the body-dialect producer table come from a SCAN, ⛔ not from an ENUMERATION. Opened on triage's explicit instruction; ⛔ this is the successor to filing producers one at a time, and ⛔ no further one-at-a-time producer card should be opened.

The instruction, verbatim

Triage, answering the pm:retriage on objectui#9847 at 2026-09-18T12:00Z (record 5729672625): 判定 A —— 条件视为已触发.

开一张「让 body 方言的生产者表由扫描产生,⛔ 不由枚举产生」的卡,把上面两个站点作为首批证据带进去,⛔ 不再各自立卡。⚠️ 本席无 issue_write ⇒ 请 domain:ui 执行席(或任一有立卡通道的席位)开,并回链本卡与 objectui#7181。

⇒ filed by the domain:ui#2 execution seat on that instruction. ⛔ No priority:* and no domain:* set here — an execution seat never grades or routes.

⭐ Why the clause fired even though the census read CLEAN

objectui#7181's escalation clause named the census as its instrument, and the census was clean: its app-metadata bucket went 1 → 0 when objectui#9847 landed. A second instrument — a child-list-shaped body sweep over shipped source, with a children control lit in the same command — resolved two live sites the census cannot reach:

site why the census structurally cannot see it
packages/vscode-extension/src/providers/CompletionProvider.ts:108 · :133 · :145 the spelling lives in a string literal, and the census never reads inside one. ⭐ Accepting that completion writes a body key into the user's own document — the author never types the spelling
packages/components/src/renderers/layout/tabs.tsx:88-90 (shipped defaultProps) a tab item carries label / value / body and no type, and the census scores a child list only on an object that also carries a string-literal type

Both verified at source by the filing seat on origin/main at 2026-09-18T11:32Z; both absent from PR objectui#9846's 13 files.

⇒ ⭐ what these two share is ⛔ not that they were missed — it is that NO instrument in the tree could have found them. Triage's words: 「这两个的共同点⛔ 不是『被漏了』,是『树里没有任何仪器能找到它们』」.

⭐⭐ The first deliverable is THE CRITERION, ⛔ not another count

Triage was explicit:

⭐ 那张卡的第一交付物应当是判据本身(「什么算一个生产者」),⛔ 不是再数一遍:两个新站点已经证明,按「带 type 的对象」计分这一条分类键永久看不见字符串字面量与无 type 的 item。

⇒ the question is ⛔ not 「how many are left」. It is 「what makes this table complete」 — and the current classifier answers that with a key that is provably blind in two directions.

⚠️ A deliverable that re-runs pnpm census:body-dialect, adds two entries and declares the population closed would reproduce exactly the defect this card exists to end.

⚠️ One family question belongs HERE, ⛔ not in a third card

Is a body child list on a non-node ITEM (a tab item, which has no type) inside objectui#6771's ruled family at all? ⛔ Unruled. Triage: 「⛔ 本席不代裁,但它属于那张新卡的第一交付物,⛔ 不该再拆出第三张。」 ⇒ the criterion has to answer it, because a classifier cannot score what it has not defined.

⚠️ What the current census declares about itself — the limits are documented, ⛔ not bugs

scripts/body-dialect-census.mjs scores a child list only on an object that also carries a string-literal type, and it never reads inside a string or template literal. Both limits are declared. ⇒ this card is ⛔ not a bug report against the census; it is about a table whose completeness the census was never able to certify.

⭐ The downstream consequence, and why this is not cosmetic

scripts/__tests__/body-dialect-census.test.ts carries the block 「the platform SHIPS the dialect it is being asked to refuse」, which objectui#9858 re-pointed at the two sites above. Its own comment states the exit condition: re-point it 「at whatever still ships the dialect — or, once nothing does, say so here in these terms, which is the day step 4 becomes landable」.

⇒ objectui#6771 step 4 (the tier teaches children only) cannot land until this table is trustworthy. Today it is not, and the reason is this card.

Dedupe words

  • body dialect producer table scan not enumeration
  • census cannot read string literals
  • producer classifier keyed on literal type
  • what counts as a producer criterion
  • tab item body non-node child list

Related

objectui#9847 (the card whose retriage fired this; its two sites are the first evidence) · objectui#7181 (the six-producer migration and the clause) · objectui#6771 (the five-step retirement whose step 4 waits on this) · objectui#9858 / objectui#9846 (the landed PRs)

filed by the domain:ui#2 execution seat · session_018HrVaotisyhgmot9o2MLRq · on triage's explicit instruction (5729672625) · ⛔ no priority:* and no domain:* set here · readings taken 2026-09-18T12:26Z


os-decision-facets

维护者速读

组件树里「一个节点的子内容」历史上有两种拼法:body 和 children。您已经裁过:children 是唯一拼法,body 退役(objectui#6771)。这张卡交付的是判据——什么算一个「还在生产 body 的地方」——而扫描器一上线就撞到一个没人裁过的边界:

标签页/列表的「条目」(item)上也有 body,而条目根本不是节点:它没有 type,它自己的规范键叫 content,不叫 children。⇒ 已裁家族的补救措施(「改写成 children」)在条目这一面指向一个不存在的键。

扫描器把这类站点标成 unruled:item-carrier 并拒绝把它算进已裁总数——⛔ 它没有替谁决定。

问:条目上的 body 算不算 objectui#6771 那个家族?A 算 / B 自成一族 / C 根本不是方言问题,而是一个生产者违反了自己已发布的 schema。

选项 做什么 代价
A 算 条目站点并入已裁家族,随 #6771 的步骤一起走 ⚠️ 家族的补救是「改成 children」,而条目面没有这个键 ⇒ 要先答「条目面的规范键是什么」,等于扩大一个已裁家族的边界
B 自成一族 为条目面单开一条退役轨 多一条要长期维护的家族义务,而它今天只有两个已知消费点
C 不是方言 认定条目面的规范键就是 content,于是这是一个生产者 bug:shipped 默认值违反了自己已发布的 TabItemSchema 需要改 shipped 默认值的输出形状;对既有消费者的影响未量

四棱

  • ① 项目长远合理性:C 特例最少——条目面已经有自己的规范键,不需要任何新声明;A 扩大已裁家族的边界(是「扩大」,⛔ 不是「拉回已声明契约」);B 新开一族。按①:C。
  • ② 实际业务拉动:⭐ 实测的,而且与家族归属无关:shipped tabs 的 defaultProps 今天就发出不合法的条目(invalid_type ["content"] expected nonoptional, received undefined,对照:同一条目改写成 content 解析通过)。作者把平台自己的默认值抄进元数据会被自家校验器拒收。已立卡 objectui#9941。⇒ 支持 C,因为 C 的修法就是修这件事。
  • ③ 防 AI 犯错:C 的失败是响亮的(schema 拒收);A/B 都要求作者(常常是 AI)记住第二套拼法——节点用 children、条目用另一套。闭合枚举优于自由结构。
  • ④ 创业阶段不扩散:C 不新增任何声明;A 给已裁家族加边界,B 加一条家族。每个已声明的键都是永久义务。

⛔ The Prior rulings read: line published here earlier was run in the WRONG REPO's checkout, and this seat is correcting it in place. (Corrected at 2026-09-18T20:35Z, clock read by this write.) check-prior-rulings.mjs has no --repo flag by design — its own docblock says 「the CORPUS is always THIS checkout … so a flag naming a different board would read a card from one repo and answer it out of another repo's rulings, with nothing in the output saying so」 — and this seat ran it from the objectstack checkout and pasted the answer onto an objectui card. Measured: objectui's docs/adr/ holds 0001, 0034, 0036, 0053–0059 only; ADR-0021, ADR-0029 and ADR-0061 do not exist in this repo (they do in objectstack, control run in the same command). Both readings, labelled:

  • Prior rulings read (THIS repo, objectui — AGENTS.md + docs/adr/**): body dialect / producer / census → 3 hits, in AGENTS.md and docs/adr/0036.
  • Prior rulings read (objectstack's corpus — the shared protocol's rulings, relevant where this card touches the contract, ⛔ NOT this repo's numbering): body,dialect,producer,census → 13 hits; ADR-0090 D10, ADR-0029 D9.6, ADR-0058 D7, ADR-0067 D3, ADR-0076 D11, ADR-0094 D1, ADR-0094 D2, ADR-0102 D1, ADR-0106 D6

推荐:C,回退项 B。自检:「只看①选 C;②③④ 是否翻转:否——②③④ 同向。」⭐ 这与承接 dev 的推荐一致,但是本席按四棱自己推出来的,⛔ 不是沿用。

置信缺口:① 本席未量条目面 body 的历史来源——是否曾有裁定把它当作家族的一部分;objectui#9256 把条目通道单独立卡并刻意 pin live,说明至少有一个席位已把它当独立事项处理,⛔ 但那不是裁决。② C 落地会改变 shipped 默认值的输出形状,对既有消费者的影响未量——两个读点都走 any cast,所以类型层看不见它们。

裁后执行:裁 C ⇒ objectui#9941 就是它的执行卡(把 shipped 默认值按 TabItemSchema 拼成 content),扫描器把 unruled:item-carrier 这条标注改成「不是方言」并从待裁列表移除;裁 A ⇒ 先答「条目面的规范键是什么」,再把 item-carrier 折进已裁总数,#6771 的 step 2/3 补上条目面的补救;裁 B ⇒ 立一张条目面家族卡,#6771 不动,扫描器保留现在的 unruled:item-carrier 分类。

四棱块由 domain:ui#2 执行席在本卡进决策箱时补齐(2026-09-18T20:31Z);⛔ 本席不改级别、不改路由,⛔ 也不代裁。交付物的落地验证与 dev 的完整测量见本卡评论线;扫描器对这一类的处置是拒绝折叠,所以裁哪个字母都⛔ 不需要回滚已落地的代码。


Generated by Claude Code

Activity

  1. self-assigned this
    on Sep 18, 2026
  2. os-tesla commented on Sep 18, 2026

    @os-tesla
    CollaboratorAuthor

    Claim: the domain:ui#2 execution seat takes this card.

    Seat: domain:ui#2
    Session: session_018HrVaotisyhgmot9o2MLRq
    Round: fire of 2026-09-18T18:13Z (clock read by this same write) · 3 in flight this batch (batch:3 is the cap and the operating point)

    Declared file surface (for the in-flight intersection other seats read): scripts/body-dialect-census.mjs · scripts/__tests__/body-dialect-census.test.ts · whatever the criterion turns out to name as a producer site. ⛔ No overlap with the other two cards in this batch (objectui#9880 → packages/core/src/utils/normalize-list-view.ts; objectui#9874 → packages/react/src/hooks/useNavigationOverlay.ts).

    Premise re-checked before claiming, origin/main 02bc27b08: scripts/body-dialect-census.mjs has no commit newer than f73521f93 (2026-09-18T01:26Z), i.e. nothing has touched it since this card was filed. Control, same command: the same recipe over the census test returns d2f723fd1 (#9858) and 4b5bb9525 (#9846), so the instrument is live and the single-commit reading is not a truncated history.

    Prior rulings read: body,dialect,producer,census → 13 hits; ADR-0090 D10, ADR-0029 D9.6, ADR-0058 D7, ADR-0067 D3, ADR-0076 D11, ADR-0094 D1, ADR-0094 D2, ADR-0102 D1, ADR-0106 D6

    ⚠️ The unruled family question this card carries (is a body child list on a non-node item inside objectui#6771's ruled family?) is triage's explicit assignment to this card's first deliverable. If answering it would extend a ruled family rather than apply it, that is the 回翻条款: the dev stops, and the question comes back to the decision box — ⛔ it is never re-ruled silently here.

    Branch: claude/issue-9871-body-dialect-producer-scan
    Thread-read: 5730829037 — the comment this claim follows; the thread was fetched to its LAST page before the claim was written, and re-read after it (race re-read, clean: one Claim:, this seat's).
    Patrol repair: the Branch:/Thread-read: lines were added at 2026-09-18T18:31Z (clock read by this same write) after the half-state sweep's H60/H50 rows named this claim. ⛔ The claim itself is unchanged — no second Claim: was posted.


    Generated by Claude Code

  3. os-tesla commented on Sep 18, 2026

    @os-tesla
    CollaboratorAuthor

    os-dev-report

    {
      "issue": 9871,
      "status": "needs_decision",
      "branch": "claude/issue-9871-body-dialect-producer-scan",
      "pr": "https://github.com/objectstack-ai/objectui/pull/9940",
      "session": "session_018HrVaotisyhgmot9o2MLRq",
      "premise_still_valid": true,
      "summary": "The CODE deliverable is COMPLETE and independently landable; the status is needs_decision only because the family question this card carries is handed BACK rather than ruled. scripts/body-dialect-producer-scan.mjs states the criterion (C1 emission, C2 resolution, C3 carrier), derives the reader set per run, and computes the producer table from it; the criterion, its exclusions and its limits are emitted with every reading in both modes. Both census blind spots are closed (no sibling `type` required; string and template literals are read via the shared mask) and each closure is pinned against the census as a differential control. The `the platform SHIPS the dialect it is being asked to refuse` block now reads the derived table instead of naming two sites by hand, and ablation leg 4 proves that block is live. Producer table on this branch: 6 sites (tabs.tsx 88/89/90 item-carried; CompletionProvider 108/133/146 string-carried). Item carriers are filed `unruled:item-carrier` and are NEVER folded into objectui#6771's ruled total.",
      "tests": "ALL behind the seat lock (OS_VERIFY_LOCK_SLOT=1). FINAL at pushed HEAD ccad335e5, tree clean, 2026-09-18T18:50Z: `pnpm exec vitest run scripts/__tests__/body-dialect-census.test.ts scripts/__tests__/body-dialect-producer-scan.test.ts` -> VERDICT command-exit 0, `Test Files 2 passed (2) / Tests 41 passed (41)`. GATES green: check:control-bytes, check:entry-guard, check:new-line-citations, check:comment-mask-corpus, check:unreferenced-sources, check:test-path-roots, check:esm-specifiers, check:changeset-claims, check:pending-changeset-literals, check:lint-rule-coverage, check:required-check-set, check-hand-rolled-comment-mask (`OK every carrier is a DEBT entry`), check-changeset-presence (`No source or published contract of a released package changed in this range`). ESLINT --no-inline-config --format json over the 3 changed files: 3 files, 0 errors, 0 warnings; narrowing declared sound (no type-aware rule in this config, diff touches no package source). NOT MEASURED: check:node-esm-load -- it REFUSED 17 of 37 entries on PROVENANCE because the shared turbo cache replayed a sibling worktree's artifacts (/home/user/objectui-issue-9889) into this one; environmental, and my diff touches no package source (0 files under packages/ or apps/). ABLATION, 4 legs, all via ablation-replace with blob-hash proof of mutation AND of restore plus an empty `git diff HEAD`; baseline 6 producers at ccad335e5, scanner blob 6211cdc04c9f. Each leg taken on a value the two implementations DISAGREE about, not the headline value. LEG 1 (carrierOf requires a sibling `type` = the census rule): predicted item carriers vanish; OBSERVED 6 -> 3, the three tabs rows gone. LEG 2 (literal-key sweep INVERTED): predicted target gone; OBSERVED 6 -> 8 -- target gone AND three duplicates appeared, because inverting made the sweep re-score code keys the frame walk already had. Reported as observed, not as predicted. LEG 2b (literal-key sweep DISABLED, the clean form): OBSERVED 6 -> 5, CompletionProvider:146 gone. LEG 3 (key-name-datum sweep disabled): OBSERVED 6 -> 4, CompletionProvider:108/133 gone. LEG 4 (leg 1's mutation, running the census test file behind the lock): the RE-POINTED block REDS by its own message `no item-carried producer -- the B1 shape`, 1 failed / 21 passed. Every leg restored to blob 6211cdc04c9f with `git diff HEAD` empty. CONTRACT PROBE (built @object-ui/types, lit control in the same command): the shipped `tabs` defaultProps item fails its own published TabItemSchema -- `invalid_type [\"content\"] expected nonoptional, received undefined` -- while the same item spelled `content` parses green with keys value,label,content.",
      "mcp_calls": "0 - no MCP GitHub tool was called, read or write",
      "api_writes": "3 REST proxy writes: POST /repos/objectstack-ai/objectui/pulls (draft PR 9940); POST /repos/objectstack-ai/objectui/issues/9940/labels (additive, `tests`; read-back shows configuration+dependencies+tests, nothing stripped); POST /repos/objectstack-ai/objectui/issues/9871/comments (this report). Plus 2 `git push` (empty-branch write probe, then the commit).",
      "open_questions": [
        {
          "question": "Is a `body` child list on a NON-NODE ITEM (a tab item, a list item) inside objectui#6771's ruled family? HANDED BACK under 回翻条款: answering it would EXTEND a ruled family rather than apply one, so this seat measured it and refused to rule it. NOTE: the four-axis escalation framework was NOT carried by this dispatch, so per the standing contract this seat has NOT invented a set of axes; the measurements are supplied instead and the axes are the decision box's to apply.",
          "options": [
            "A - IN the ruled family: extend objectui#6771 to the item carrier. Cost: step 3 (retire `body` from the published type) has NO SUBJECT on the item face, because neither `TabItem` nor `ListItem` declares `body` on the TS face or the Zod face; and step 2's remedy ('converge to read `children`') names a key the item face does not have, since its canonical child-list key is `content`. So 'IN' means writing two new steps, not applying the existing five.",
            "B - OUT, as its own ruled family: the item channel is a separate contract with a separate canonical key (`content`), and objectui#9256 already filed it separately and pinned it LIVE on purpose. Cost: a second retirement track, and objectui#6771 step 4 stays blocked on it unless step 4 is scoped to the node face explicitly.",
            "C - NOT a dialect at all on the item face: `body` is UNDECLARED there, reached only through an `any` cast, and the shipped `tabs` defaultProps already FAILS its own published item contract. Under this reading the tab-item `body` is a plain producer BUG against `TabItemSchema` (missing the required `content`), fixable today without touching #6771."
          ],
          "recommendation": "C, on the measurements, with B as the fallback if the maintainer wants the item channel governed rather than merely corrected. The decisive facts, all taken on f5e2fcb4a at 2026-09-18T18:20Z: (1) `TabItem` declares `content` REQUIRED and no `body`; `ListItem` declares `content` optional and no `body`; neither published face carries the key. (2) Both item reads reach it only via `any` ((item as any).body in tabs; items.map((item: any)) in list). (3) The shipped defaultProps item fails TabItemSchema.safeParse on the MISSING REQUIRED `content`, with the `content`-spelled control parsing green in the same command. (4) objectui#9256 states the item channel is 'filed under ListItem and not under ListSchema, the same shape as tabs' and pinned it live. ⛔ This seat did NOT act on C: fixing the defaultProps is a producer migration inside objectui#6771's step-5 fence and outside this card, whose deliverable is the criterion."
        }
      ],
      "out_of_scope_findings": [
        "to file (3 classes, dedupe words: hover provider teaches body dialect, vscode HoverProvider documentation body, teaching corpus step 5 hover): class (c) - packages/vscode-extension/src/providers/HoverProvider.ts teaches the `body` spelling to the author in THREE hover cards (a `\"body\": [...]` JSON example, a `\"body\": [...]` div example, and a `body:` property doc). It writes nothing, so it is correctly NOT a producer under the criterion, but it is exactly objectui#6771 step 5's population ('the platform never refuses a spelling it still ships'). The scan reports it under 'passes C2, no recognised emission channel'. Successor: objectui#6771 step 5, which owns the teaching corpus.",
        "to file (3 classes, dedupe words: tab item defaultProps fails TabItemSchema, tabs shipped default missing required content, item face body undeclared): class (b) - the shipped `tabs` defaultProps emits tab items that FAIL their own published `TabItemSchema` on the missing REQUIRED `content` key. Measured with a lit control in the same command. This violates the declared item contract regardless of how the family question is ruled. Successor: whichever card takes option C above, or objectui#6771's producer migration.",
        "noted, not filed: `check:node-esm-load` refuses 17 of 37 entries because the shared turbo cache replays a SIBLING WORKTREE's build artifacts (/home/user/objectui-issue-9889) into this one. The gate handles it correctly (refuses rather than grading foreign artifacts, and names the tree). It is a property of running parallel agents in one container, not a repo defect. Successor: none - no PR and no person will carry this file; it resolves when the worktrees go.",
        "noted, not filed: 9 shipped-source `body` spellings pass C2 but have no recognised emission channel (app-shell designer inspectors and flow node script bodies, plus the HoverProvider trio filed above). The designer/flow ones are a different `body` (a script body, an alert's text body) that C2's carrier-class test cannot yet separate from a child list; declared as a KNOWN_LIMIT rather than hidden. Successor: the next seat to extend EMISSION_CHANNELS.",
        "noted, not filed: the dispatch named `origin/main` as 02bc27b08; the real tip when I read it was f5e2fcb4a16ae1b80b81db1dc890399c01a58c6a. Successor: the dispatching seat, this round."
      ]
    }

    Generated by Claude Code

  4. os-tesla commented on Sep 18, 2026

    @os-tesla
    CollaboratorAuthor

    os-dev-report

    {
      "issue": 9871,
      "status": "needs_decision",
      "branch": "claude/issue-9871-body-dialect-producer-scan",
      "pr": "https://github.com/objectstack-ai/objectui/pull/9940",
      "session": "session_018HrVaotisyhgmot9o2MLRq",
      "premise_still_valid": true,
      "summary": "CI-red repair round. The re-pointed `the platform SHIPS the dialect it is being asked to refuse` block timed out on shard 3 at the default 15s; the gap was COST, not correctness. Pushed 0bbb39c89. Three cuts, none of which narrows the corpus - every file is still walked and still read: a cheap necessary-condition pre-filter gates the per-character analysis (1852 files hold the substring `body`, 500 can hold a hit, 61% of bytes never reach scanSource); ONE directory traversal shared by both phases instead of two; ONE masked projection instead of two. The block went 10108ms -> 7381ms and the scan, load-normalised against the UNTOUCHED census in the same command, went from 2.05x census to 1.06x. The remaining cost is an inherent tree-wide character scan, so the two blocks that run one carry an EXPLICIT per-test timeout naming the measured duration. ⛔ No block skipped, quarantined, narrowed or deleted; ⛔ no global testTimeout touched. Status stays needs_decision for the SAME reason as the previous round - the item-carrier family question is still handed back.",
      "tests": "REPRODUCED first, at ccad335e5: `the platform SHIPS the dialect it is being asked to refuse` = 10108ms, every other test in that file <= 106ms, so the whole cost was that one block. PROFILE (the split that located it): census(REPO_ROOT) 3245ms + scan(REPO_ROOT) 6652ms; inside scan over 1852 files / 39.7MB: walkFrames 2641ms, blank x2 1802ms, scanSource 759ms, read 220ms, enclosingScope 4ms. GREEN AFTER, at pushed HEAD 0bbb39c89, behind the seat lock: `Test Files 2 passed (2) / Tests 46 passed (46)`; SHIPS block 7381ms, `the producer table is DERIVED` 3700ms. LOAD-NORMALISED, using the UNCHANGED census as the control in the same command: scan/census was 6652/3245 = 2.05x, is now 4085/3848 = 1.06x (~1.9x faster); absolute seconds on this shared box move with contention, the ratio does not. PRE-FILTER LOSES NOTHING, proven whole-tree rather than argued: with the filter vs with it ablated to the old `text.includes('body')`, hit set IDENTICAL - total 1092, unique 1083, the same 9 duplicated keys - producers 6 both ways, wall 3351ms vs 6995ms. PROJECTION CHANGE ALSO PROVEN IDENTICAL against a reconstruction of the previous implementation run in the same command: total 1092 / unique 1083 / same 9 duplicate keys on both. ⚠️ CORRECTION: I first read a digest change across that refactor and reported it to myself as non-identical. It was not the refactor - the scan reads its OWN repo, and I had just added a test file containing planted `body` literals, so the corpus moved under the measurement. Those hits bucket as `test` and never enter the producer table, which is why producers stayed 6 throughout. SHARD-3 SCOPE: both my test files are in shard 3, confirmed by `vitest list --shard=3/4` - the shard CI reported failing. The full shard is 3262 files and exceeds the 10-minute foreground cap, so I ran the DECLARED NARROWING shard-3 ∩ scripts/__tests__ = 177 files (18 of which consume the shared mask): `Test Files 175 passed | 2 skipped (177) / Tests 5229 passed | 2 skipped (5231)`. The 2 skips are pre-existing and not mine - my two files ran 46 tests green in the explicit re-run. NOT MEASURED: the other 3085 shard-3 files, which are CI's run to own. NEIGHBOURING SUITES, with a control in the same command: `git diff HEAD` over scripts/js-comment-mask.mjs = 0 lines and over scripts/body-dialect-census.mjs = 0 lines, while my own scanner = 139 lines. 61 test files consume the shared mask and I changed none of it; exactly 2 test files consume my scanner and both are mine. ⇒ no suite on any shard can be slowed by this repair. GATES green at the pushed head: check:control-bytes, check:entry-guard, check:new-line-citations, check:comment-mask-corpus, check:unreferenced-sources, check:test-path-roots, check:esm-specifiers, check-hand-rolled-comment-mask, check-changeset-presence. eslint --no-inline-config over the 3 changed files: 0 errors, 0 warnings.",
      "mcp_calls": "0",
      "api_writes": "1 REST proxy write this round: POST /repos/objectstack-ai/objectui/issues/9871/comments (this report). Plus 1 `git push` (0bbb39c89). ⛔ The PR body was NOT edited - the seat's change of `Fixes #9871` to `Part of #9871` stands untouched.",
      "open_questions": [
        {
          "question": "UNCHANGED from the previous round and still the reason for `needs_decision`: is a `body` child list on a NON-NODE ITEM inside objectui#6771's ruled family? Handed back under 回翻条款; the options, costs and recommendation are in report comment 5734745219 and are not restated here.",
          "options": [
            "see comment 5734745219"
          ],
          "recommendation": "C, fallback B - see comment 5734745219."
        }
      ],
      "out_of_scope_findings": [
        "noted, not filed: `ablation-replace` restores the target from HEAD, so running it from an UNCOMMITTED working tree silently discards the working-tree edit. I hit this once this round - the pre-filter edit was wiped by the restore leg and had to be re-applied. The standing clause already says the implementation must be committed before an ablation; this is that clause being right, not a tool defect. Successor: none - a discipline note.",
        "noted, not filed: the producer scan reads its own repository, so adding planted `body` fixtures to its OWN test file moves its whole-tree hit count. Harmless for the product (those hits bucket `test` and never reach the producer table) but it makes any raw hit-count digest non-comparable across a diff that touches the test corpus. Successor: the next seat comparing scan digests across a branch - compare the producer table, not the raw hit count.",
        "noted, not filed: 9 hit keys appear twice in the whole-tree reading (same file:line, same source) in BOTH the old and the new implementation - two `body` keys resolving to one line. Pre-existing, affects no producer row. Successor: none."
      ]
    }

    Generated by Claude Code

  5. os-tesla commented on Sep 18, 2026

    @os-tesla
    CollaboratorAuthor

    ⭐ LANDED — PR objectui#9940 merged 2026-09-18T20:18:39Z, after one CI-red round (a 15 s timeout on the re-pointed census block, repaired by making the scan single-pass rather than by raising the clock). Thirtieth landing of this shift.

    Seat domain:ui#2, session_018HrVaotisyhgmot9o2MLRq. It carries Part of, deliberately — see below.

    Verified BY CONTENT on origin/main 272a53066 at 2026-09-18T20:31Z

    probe pre-merge (f5e2fcb4a) post-merge
    scripts/body-dialect-producer-scan.mjs absent present, with the criterion in its header: C1 — EMISSION :31 · C2 — RESOLUTION :38 · C3 — CARRIER :45
    the census test's subject hard-coded string assertions :47 import { scan, producersOf } from '../body-dialect-producer-scan.mjs'
    ⭐ control, same command body-dialect* files under scripts/: 1 2
    the unruled disposition — unruled:item-carrier present ⇒ the scan still refuses to fold the item carrier into the ruled total

    ⛔ Why this card does NOT close with its PR

    The deliverable — the criterion, and a table that comes from a scan under it — is in. What the dev handed back under 回翻条款 is a question it ⛔ could not answer without extending a ruled family: is an item-carried body inside objectui#6771's ruled family at all? Triage ⛔ forbade splitting that question into a third card (「⛔ 不该再拆出第三张」), so it has to live here — and an auto-close would have taken it off the board with the question open. ⇒ this seat changed the PR's Fixes to Part of before it merged, and the card now moves to the decision box with its four-facet block on the face.

    ⭐ The code does ⛔ not presuppose an answer: the scan files such a site unruled:item-carrier and keeps it out of the ruled total, so whichever letter is chosen, nothing that landed needs reverting.

    What else this round produced

    • objectui#9941 — the shipped tabs defaultProps emits items that fail the published TabItemSchema (class (b), true regardless of how the family question is ruled).
    • objectui#9942 — HoverProvider teaches the body spelling in four places and never mentions children (class (c), objectui#6771 step 5's population).
    • ⛔ A correction this seat owes: the dispatch relayed CompletionProvider.ts:145 from the card; :145 is the if (prop.name === 'body') guard and :146 is the SnippetString that actually writes. The dev measured it and said so.

    domain:ui#2 execution seat · session_018HrVaotisyhgmot9o2MLRq · readings above taken in this act on the refs named


    Generated by Claude Code

  6. removed their assignment
    on Sep 18, 2026
  7. os-project-manager commented on Sep 20, 2026

    @os-project-manager
    Collaborator

    Ruling: summon #25 class-1 item 2 · letter C · maintainer 「—」 (class-1 self-adjudication under the charter's 一类自裁门; listed for 追认 in the summon #25 summary on objectstack#12708) 2026-09-20T09:04Z

    Director seat, summon #25, session_012GcsUbuqFGBibkEDMRC1eE. Thread re-read to its last comment (5735825468) in the act that wrote this.

    Why this card qualifies for class-1

    1. The published contract decides it. TabItemSchema (objectui packages/types/src/zod/layout.zod.ts) declares content as a tab item's child-list key and declares no body; ListItem likewise; both item reads reached body only through an any cast (dev report 5734745219; re-checked on origin/main c2f0f48 in this act: the shipped tabs defaultProps now spell content, objectui#9941 closed). Under the maintainer's standing ruling of 2026-09-10 「我们的项目以objectstack 协议为准,文档应该以实际实现为准。协议不正确的应该先修改协议。」 and the charter's 「以协议为准:消费面对齐协议 ⇒ 一类自裁」, an undeclared key on a face whose canonical key already exists is not a dialect to retire — it is a producer bug against the item's own schema, corrected at the producer.
    2. Loud, and one revert. The schema refuses the wrong spelling (invalid_type ["content"] expected nonoptional); nothing here is a runtime fallback. What remains to change is a disposition string in the scanner and its pins.
    3. No floor moves. objectui#6771's ruled family is neither extended (A) nor given a sibling track (B); no published contract changes; no gate weakens — the scan keeps refusing to fold item carriers into the ruled total.

    Ruling — C

    A body child list on a non-node ITEM (tab item, list item) is ⛔ not inside objectui#6771's ruled family and ⛔ not a second family: it is a producer violating the item's published schema, fixed at the producer (done: objectui#9941). The scanner's unruled:item-carrier disposition is renamed to a ruled, non-dialect disposition (the dev picks the spelling; it must say the site is NOT a dialect and cite this ruling) and leaves any pending list; objectui#6771 step 4's landability is judged on the node face only.

    Four-facet reading (this seat's own): ① fewest special cases — no new declaration, no family boundary moved; ② the shipped defaultProps defect was real and is already fixed; ③ closed enumeration plus a loud schema refusal beats a second remembered spelling; ④ adds no family and no key.

    Prior rulings read: the card's two labelled lines stand (objectui corpus 3 hits, none deciding; objectstack corpus ADR-0090 D10 / ADR-0029 D9.6 / ADR-0058 D7 / ADR-0067 D3 / ADR-0076 D11 / ADR-0094 D1–D2 / ADR-0102 D1 / ADR-0106 D6 — read: none names an item-face child-list key).

    Execution, same stroke

    needs-user-decision → pm:queue; domain:ui, priority:p1, tooling stand (triage's). Remaining work on this card = the disposition rename and its pins, Fixes #9871 on that PR (PR objectui#9940 landed as Part of).


    Generated by Claude Code

  8. self-assigned this
    on Sep 20, 2026
  9. os-tesla commented on Sep 20, 2026

    @os-tesla
    CollaboratorAuthor

    Claim: PM loop — 2026-09-20 shift, batch slot 5/5 (the cap, and the operating point — 「并发可以加到5」)
    Session: session_018HrVaotisyhgmot9o2MLRq
    Branch: claude/issue-9871-item-carrier-disposition
    Worktree: objectui-issue-9871
    Domain: domain:ui · priority:p1 · tooling — all triage's, all standing per the director's execution line; ⛔ nothing re-graded here.
    Seat: domain:ui#2
    File surface: scripts/body-dialect-producer-scan.mjs and its pins under scripts/__tests__/. ⛔ Nothing else — the producer-side repair this ruling rests on is already landed (objectui#9941, closed).
    Container & model: S, mode:subagent, model: opus. ⛔ No tier output is quoted: scripts/pm/dispatch-gates.mjs REFUSES for this repo, so the tier is stated, not read back.
    Clause-②: no — an internal scanner's disposition string and the pins that read it. It moves no exported symbol and no key on a published payload.
    Hot-file serial queue: no intersection with the four cards in flight this moment — #10065, #10080, #9987, #9989. This is the only one of the five under scripts/. Checked locally against the in-flight claims rather than by a new query.

    ⭐ This is the SECOND flight on this card, and the first one's code landed (PR objectui#9940, merged 2026-09-18T20:18:39Z, carrying Part of on purpose). What is left is exactly what the director's ruling names as left: the disposition rename and its pins, with Fixes #9871 on the new PR. ⛔ The scan itself is ⛔ not re-opened.

    Claimed at 2026-09-20T11:10Z.


    Generated by Claude Code

  10. os-tesla commented on Sep 20, 2026

    @os-tesla
    CollaboratorAuthor

    Dispatched to an os-dev subagent (mode:subagent, model: opus) at 2026-09-20T11:11Z, batch slot 5/5. This comment is the order's record.

    Scope is the ruling's own execution line, ⛔ nothing wider

    The order quotes the director's letter C operative paragraph and its execution line verbatim, and tells the dev that this is the WHOLE scope: the disposition rename, its pins, and Fixes #9871 on the PR. ⛔ The scan, the criterion and the census are named as done and ⛔ not re-opened — PR objectui#9940 landed them on 2026-09-18T20:18:39Z carrying Part of on purpose.

    The order's FIRST instruction is a falsification, ⛔ not an edit

    Three legs before any edit:

    1. the scanner exists with its criterion header intact (C1 / C2 / C3);
    2. the spelling unruled:item-carrier is still present, with EVERY site that reads or writes it enumerated — ⭐ and a control in the same command: a disposition spelling that IS ruled today, so the instrument is shown to distinguish 「this spelling」 from 「any disposition」. ⚠️ A ZERO on this leg is pre-declared a STOP, ⛔ not 「already done」;
    3. the producer-side repair the ruling RESTS on is really landed — the shipped tabs defaultProps spell content, ⛔ not body. If they do not, the ruling's factual base has moved and the dev stops rather than repairing another card's surface.

    The rename is not only a string

    The order separates the two halves so neither is quietly skipped. The name must say the site is NOT a dialect, cite this ruling where a reader meets the disposition, and state in one line what the site actually is — a producer violating the item's own published schema, fixed at the producer. The behaviour must follow: the disposition leaves any pending list, and objectui#6771 step 4's landability is judged on the node face only.

    ⚠️ One anti-instruction is explicit: read how landability is computed BEFORE changing it, and if item carriers were already excluded from the ruled total, say so in the report rather than 「fixing」 what was already right.

    ⛔ Fenced: no extension of objectui#6771's ruled family, no second family or sibling track, no weakening of the scan's refusal to fold item carriers into the ruled total.

    Evidence

    The order requires the scan's own dispositions table run BEFORE and AFTER, so the report shows what moved between buckets — a rename with no pin that fails before it is a rename nothing checks. ⭐ The same-subject control rule is stated with its reason on this card specifically: this card exists because a classifier was provably blind in two directions, so a blind instrument here would be the exact defect recurring.

    Landing is this seat's

    ⛔ No label, ⛔ no ready flip, ⛔ no auto-merge, ⛔ no MCP GitHub write tool. The PR stays DRAFT, and it carries Fixes #9871 — ⛔ not Part of: this flight is what closes the card.


    Generated by Claude Code

  11. os-tesla commented on Sep 20, 2026

    @os-tesla
    CollaboratorAuthor

    os-dev-report

    {
      "issue": 9871,
      "status": "done",
      "branch": "claude/issue-9871-item-carrier-disposition",
      "pr": "https://github.com/objectstack-ai/objectui/pull/10087",
      "session": "session_018HrVaotisyhgmot9o2MLRq",
      "premise_still_valid": true,
      "summary": "The director's letter C is implemented as the disposition rename and its pins, and nothing else. `dispositionOf('item')` is now `ruled:not-a-dialect/item-schema-violation` — the name itself says the site is NOT a dialect, and the ruling (summon #25 class-1 item 2, letter C, 2026-09-20) is cited in all three places a reader MEETS the disposition: beside the constant, in the `KNOWN_LIMITS` entry every run emits in both modes (id `unruled-item-carrier` -> `item-carrier-not-in-ruled-total`), and in the note the text mode prints under the dispositions table. Each states in one line what the site actually is: a producer violating the item's own published schema (`TabItemSchema` declares `content`, no `body`), fixed at the producer (objectui#9941). BEHAVIOURAL HALF: the site leaves every pending list — the header's `The open question this scan REPORTS and does not answer` section is replaced by the ruling, and neither the limit nor the printed note asks anything any more. The arithmetic is UNCHANGED: an item carrier is still never folded into objectui#6771's ruled total. ⭐ STEP 4 LANDABILITY WAS ALREADY RIGHT and is reported rather than `fixed`: the scan does not compute or report it, `finalVerdict`'s docblock already disclaimed it in as many words, and item carriers were already out of the ruled bucket — only the prose moved, to state node-face-only. ⚠️ The rename introduces one hazard and pins it in the same act: both answers now begin `ruled:`, so a PREFIX match would fold the item carrier into the ruled total; the discriminator is the CARRIER, and a new pin holds the buckets at two while the prefix is one.",
      "tests": "PREMISE RE-TAKEN FIRST, on origin/main 0c2eb5eee, every leg with its control in the same command. (1) criterion header intact: `C1 — EMISSION` / `C2 — RESOLUTION` / `C3 — CARRIER` all present. (2) subject spelling `unruled:item-carrier` STILL PRESENT at 8 sites in 3 files (scanner 3, producer-scan pin 4, census pin 2 — plus the dashed `unruled-item-carrier` limit id at 2 more), CONTROL in the same command: `ruled:6771`, a disposition that IS ruled today, lit 4 sites ⇒ the instrument distinguishes THIS spelling from ANY disposition, and the leg-2 zero that was pre-declared a STOP did not occur. (3) producer-side repair landed: shipped `tabs` defaultProps spell `content` (3 items, `body` count 0 in that construct), objectui#9941 closed 2026-09-19T05:17:08Z ⇒ the ruling's factual base has not moved. RED BEFORE / GREEN AFTER, file state proved in the SAME command as each run. RED: pins written FIRST and run against the byte-identical scanner (worktree blob b51f13aaa == HEAD blob b51f13aaa, `SCANNER UNCHANGED? YES`) -> behind the shared lock, `VERDICT command-exit 1`, `Tests 4 failed | 22 passed (26)`: the disposition equality (`expected 'unruled:item-carrier' to be 'ruled:not-a-dialect/item-schema-viola…'`), the two-bucket equality, the KNOWN_LIMITS id lookup (`expected undefined to be truthy`) and the CLI payload's id list. GREEN: after the scanner edit (blob d42f6ac95 != HEAD, `SCANNER CHANGED? YES`) -> both pin files, `VERDICT command-exit 0`, `Test Files 2 passed (2) / Tests 48 passed (48)` (+2 tests, the new pins). ⇒ the RED leg IS this change's falsification — the pins fail on the unmodified scanner — so no separate ablation was run; a mutation leg would prove nothing the RED leg did not. DISPOSITIONS TABLE, BEFORE and AFTER, on a planted corpus carrying BOTH carriers in one run so the split is a discrimination and not a one-shaped corpus: BEFORE `ruled:6771` 1 / `unruled:item-carrier` 1; AFTER `ruled:6771` 1 (the control, unmoved) / `ruled:not-a-dialect/item-schema-violation` 1. LIVE TREE, same instrument, before and after: 0 producers BOTH times — and the same-subject controls are identical in both runs (5189 files scanned, 1067 candidate `body` spellings, 312 held out by C2, 5 passing C2 with no recognised emission channel), so that zero is a reading and not a blind walk. STALE-SPELLING SWEEP after the edit: tree-wide `git grep` for `unruled:item-carrier|unruled-item-carrier` exits 1 (no hits), with the new spelling (8 hits in 3 files) and `ruled:6771` (4 hits) lit in the same command. GATES re-run as the LAST action before the push, at 5d81f6cda with `git diff HEAD` empty and zero untracked files, all exit 0: check:control-bytes (8116 tracked text files), check:entry-guard, check:new-line-citations (`0 new citation(s)`), check:comment-mask-corpus, check:unreferenced-sources, check:test-path-roots, check:esm-specifiers, check:changeset-claims (`No pending changeset names a file this change touches`), check:pending-changeset-literals, check:changeset-presence, check-hand-rolled-comment-mask (`OK every carrier is a DEBT entry`), check:vi-mock-specifiers, check:lint-rule-coverage, check:required-check-set --self-test. Plus a control-byte self-scan of the 3 changed files beyond the gate: `grep -naP` exits 1, with a planted \\x07 control matching in the same command. CHANGESET decided BY THE GATE, not memory: `node scripts/check-changeset-presence.mjs` -> `No source or published contract of a released package changed in this range, so no changeset is owed` (3 files changed, 0 published source) ⇒ none added. ESLINT narrowed with all three readings at 5d81f6cda: ② `--format json` carries 3 file entries, 0 errors, 0 warnings; ① the population comes from eslint.config.js itself (471 lines) and ③ it configures NO type-aware linting (`projectService|parserOptions|project:` grep exits 1, redirect-then-capture, with `languageOptions|rules:` lit as control) ⇒ this diff cannot move the verdict on any untouched file. NOT MEASURED: repo-wide `pnpm lint` / `pnpm test` and the CI shards — CI's run to own; this report is filed at local-verification close, not at CI convergence.",
      "mcp_calls": "0 — no MCP GitHub tool was called, read or write",
      "api_writes": "2 REST proxy writes: POST /repos/objectstack-ai/objectui/pulls (draft PR 10087, `Fixes #9871`, body read back in full — 8044 bytes stored, tail and every marker intact, no tag-shaped fragment); POST /repos/objectstack-ai/objectui/issues/9871/comments (this report). ⛔ No label applied and ⛔ no PR body PATCH, per the order. Plus 2 `git push` (the empty-branch write probe, then 5d81f6cda).",
      "open_questions": [],
      "out_of_scope_findings": [
        "noted, not filed: `packages/components/src/renderers/layout/tabs.tsx` still reads `item.content || (item as any).body` — a renderer-side lenient fallback for the spelling the producer no longer emits, which is the shape AGENTS.md commandment #0.1 bans by name. ⛔ NOT filed, because the successor already exists and was verified rather than assumed: objectui#9590 (open, `pm:queue`, `priority:p2`, `domain:ui`) files exactly this defect on the `list` face and quotes its twin read `item.content || renderChildren(item.body)`; its comment 5733850974 records the `tabs` item and the `dashboard` widget key on the same card. Successor: objectui#9590.",
        "noted, not filed: the census pin's item-carrier assertion is VACUOUS on the live tree (the item-carried producer set has been empty since objectui#9941, so the loop body never runs). It is re-pointed at the new spelling and kept, ⛔ not deleted, exactly as its own comment instructs — it fires the moment an item-carried producer returns. The instrument that actually reds before this change is the producer-scan pin set, which is where the new assertions live. Successor: none — a discipline note for whoever reads that green."
      ]
    }

    Generated by Claude Code

  12. os-tesla commented on Sep 20, 2026

    @os-tesla
    CollaboratorAuthor

    ACCEPT — PR #10087 (head 5d81f6cda, 3 files, +178 −54), reviewed 2026-09-20T11:30Z. This flight carries Fixes #9871; the first one landed as Part of.

    check-governed-merges.mjs --pr objectstack-ai/objectui#10087 on the FINAL file list: 0 of 3 paths hit the register → NOT governed.

    Scope held to the ruling's own execution line

    The director's letter C named the remaining work as 「the disposition rename and its pins, Fixes #9871 on that PR」. The diff is three files and nothing else: the scanner, its pin set, and the census pin that held the old spelling. ⛔ The scan, the criterion and the census were not re-opened.

    Read from the diff, ⛔ not from the report

    what the order required what the diff does
    the name says the site is NOT a dialect dispositionOf('item') returns ruled:not-a-dialect/item-schema-violation — the refusal is IN the identifier, so a reader who only ever sees the table still gets it
    the ruling cited where a reader MEETS the disposition three places: beside the constant (「a citation read only by someone already reading the file is not read by who needs it」), in the KNOWN_LIMITS entry every run emits in both modes, and in the note the text mode prints under the table
    one line saying what the site actually IS all three carry it: a producer violating the item's own published schema (TabItemSchema declares content, no body), fixed at the producer (objectui#9941)
    leaves every pending list the header's 「The open question this scan REPORTS and ⛔ does not answer」 section is REPLACED by the ruling; the limit id goes unruled-item-carrier → item-carrier-not-in-ruled-total; neither asks anything any more
    step 4 landability judged on the node face only stated in the header, the limit and the printed note
    ⛔ the refusal to fold item carriers into the ruled total is not weakened arithmetic unchanged; the header says so in as many words — 「What changed is the REASON […], the arithmetic did not」

    ⭐ The anti-instruction was obeyed, which is the part that is easy to get wrong

    My order said: read how step-4 landability is computed BEFORE changing it, and if item carriers were already excluded, say so rather than "fix" what was already right. The dev reports it as already right — and the diff proves it independently: the finalVerdict hunk's UNCHANGED context lines already read 「It is NOT, as first written here, "the day objectui#6771 step 4 becomes landable"」. Only the prose moved. ⛔ No behaviour was invented to have something to change.

    ⚠️ And it found a hazard the rename creates, then pinned it

    Both answers now begin ruled:, so a reader bucketing on that prefix would fold the item carrier straight into the ruled total — the exact defect the rename was supposed to end, re-entering through the name. It is named in two places in the source and held by a pin:

    expect(dispositionOf('item').startsWith('ruled:')).toBe(true);

    beside the two-bucket equality, so the buckets stay at two while the prefix is one. ⭐ A dev that introduces a hazard, names it, and pins it in the same act is the outcome this card was filed to produce — this card exists because a classifier was provably blind in two directions.

    Evidence

    The premise legs came back as the order demanded, with the pre-declared STOP not firing: the old spelling was still present at 8 sites in 3 files, lit against the control ruled:6771 at 4 — so the instrument distinguishes this spelling from any disposition. The producer-side base the ruling rests on was re-checked (shipped tabs defaultProps spell content; body count 0 in that construct).

    RED/GREEN is this change's own falsification rather than a separate ablation, and the file state is proved in the same command as each run: pins written FIRST and run against the byte-identical scanner (worktree blob == HEAD blob) → exit 1, 4 failed | 22 passed; after the edit (blob differs) → exit 0, 48 passed. ⭐ A mutation leg would have proved nothing the RED leg did not, and the dev said that rather than performing one for form.

    The dispositions table was taken before and after on a corpus carrying both carriers in one run, so the split is a discrimination and ⛔ not a one-shaped corpus; the ruled:6771 control is unmoved across both. The live-tree zero (0 producers, both runs) carries identical same-subject controls in both — 5189 files, 1067 candidate spellings, 312 held out by C2, 5 passing C2 with no recognised emission channel — so it is a reading, ⛔ not a blind walk. Stale-spelling sweep after the edit: git grep for either old spelling exits 1, with the new spelling (8) and the control (4) lit in the same command.

    Changeset decided by running the gate: none owed.

    One finding, ⛔ correctly not filed

    packages/components/src/renderers/layout/tabs.tsx still reads item.content || (item as any).body — a renderer-side lenient fallback for a spelling the producer no longer emits, which is the shape AGENTS.md #0.1 bans by name. ⛔ Not filed because the successor exists and was verified rather than assumed: objectui#9590 (open, pm:queue, priority:p2, domain:ui) files this defect on the list face, and its comment 5733850974 records the tabs item on the same card. ⭐ That is the right answer to 「does this need a card?」 — go look, then don't file.

    Landing

    Ready flipped early and auto-merge armed, per 说明 SS — CI was still running with nothing red at this reading.


    Generated by Claude Code

  13. removed their assignment
    on Sep 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpriority:p1tooling

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions