Repository navigation
finding(devx): check-skill-examples.mjs 的两处 --build-filter 命令同样没说它只建一个裁剪过的闭包 #7811
Description
Activity
- addeddomain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repoobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repo
on Sep 5, 2026 Claim: PM loop round R46 — port objectui#7795's landed shape to
scripts/check-skill-examples.mjs: the two precondition-path sites that print the--build-filterbuild command (:1285regular path,:1721--self-testtype-check leg) gain a scoping notice that says the build is trimmed to the judged examples' import closure, that unbuilt packages are the designed end state, and that the exact set comes from the same filter (--dry=text, "Packages in scope") — with counts derived from what the script already reads, ⛔ no second package list, ⛔ no change to--build-filter's selection logic; plus a pin inscripts/__tests__/check-skill-examples.test.tsin the shape ofcheck-doc-snippet-types.test.ts:1098(the notice names no package of its own, both sites call it)
Session:session_01FhBNJcLRZLe8M87VcUgpKr
Branch:claude/issue-7811-skill-examples-scoped-build-notice
Worktree:objectui-issue-7811
Domain:domain:devx
File surface:scripts/check-skill-examples.mjs(the two stderr sites + one exported notice function; ⛔ not the--build-filterselection, ⛔ not the scanner/judge) +scripts/__tests__/check-skill-examples.test.ts(newdescribe, existing assertions untouched); changeset bycheck-changeset-presence(rootscripts/⇒ none expected; if owed, EMPTY frontmatter). Stop on breach; explain in the report
Container & model: S, mechanical (the shape is onmainatscripts/check-doc-snippet-types.mjs:1672scopedBuildNotice(named, total)and its pin; the card names both sites),mode:subagent,model: opus— no path-derived tier mandate; default judgment tier taken
Clause-②: no (a gate's stderr prose on its could-not-run path; exit codes and verdicts unchanged)
Serial constraints cleared: no triage comment on this card (labels from the sweep; filed by the #7795 dev seat, unassigned); premise onorigin/maina8f4bd75fat 13:42Z — both sites still print the bare command with no notice (git grep -n -e '--build-filter' -e 'dry=text' -e 'Packages in scope' -- scripts/check-skill-examples.mjshits only:10header,:1241flag parse,:1285,:1721); #7795's shape is landed (scopedBuildNotice+check-doc-snippet-types.test.ts:1098); last churn on the gate is #7909 (an eslint-disable deletion); no open PR orclaude/*branch namescheck-skill-examples; this seat's devs (#5174 b22: layout README + the doc-snippet ledger; #7434 PR A: types README + one docs page + a new scripts test; PRs #8053 / #8054 queued, #8061 converging) are disjoint.⚠️ check-skill-examples.mjsguardsskills/**content but lives underscripts/— this lane's by the lane file's path rule; the diff must not touchskills/**or.claude/**.pm:queue→pm:dispatched+ assignee written in one stroke at 13:42Z; read back in the race re-read below.
Generated by Claude Code
os-dev-report
{ "issue": 7811, "status": "done", "branch": "claude/issue-7811-skill-examples-scoped-build-notice", "pr": "https://github.com/objectstack-ai/objectui/pull/8066", "head": "3b26507ba", "premise_still_valid": true, "files_changed": [ "scripts/check-skill-examples.mjs", "scripts/__tests__/check-skill-examples.test.ts" ], "line_budget": "n/a — no skills/** or published-bundle file in the diff", "summary": "Ported objectui#7795's landed shape into check-skill-examples.mjs: one exported scopedBuildNotice(named, total), called from both precondition sites (:1285 regular path, :1721 --self-test type-check leg) and nowhere else. Both counts are arguments derived from what the gate already read (state.neededPackages.size and Object.keys(state.packageDirOf).length); the text names no package and sends the reader back to the same filter via --dry=text and turbo's 'Packages in scope' line. analyze() now carries packageDirOf out in its return, the same map it already walked to resolve neededPackages. --build-filter's selection, the scanner, the judge and every exit code are untouched; nothing under skills/** or .claude/** is in the diff. Measured on this branch: the filter names 10 of 40 packages, turbo expands those to 30 in scope, and the printed command finishes with 29 of 40 carrying a dist/ — the leftover the notice now explains.", "tests": "Both sites exercised on a genuinely unbuilt worktree, exit 2 preserved at both, notice printed under each two-line remedy (quoted verbatim in the PR body). Ablation on the committed implementation dcf79b983 with a trap-based restore: HEAD blob 2b105219f == on-disk blob before (2 call sites); removed the --self-test leg's call, blob a6b6eb01b (different, so the mutation reached disk), 1 call site; vitest run scripts/__tests__/check-skill-examples.test.ts exited 1 with 2 failed / 88 passed ('is printed on BOTH precondition paths' and 'is handed numbers the gate read'); restored, blob back to 2b105219f, git diff HEAD empty, 2 call sites. Predicted direction was turn-red and that is what was observed.", "gates": { "node scripts/check-skill-examples.mjs --self-test": "0 — 52 cases pass", "pnpm check:skill-examples (after its scoped build)": "0 — 13/13 ts, 70/70 json, 'Every marked skill example holds up against the built types'", "pnpm exec vitest run scripts/__tests__/check-skill-examples.test.ts": "0 — 90 passed (6 new)", "pnpm exec vitest run scripts/__tests__/": "0 — 111 files, 3333 tests", "pnpm type-check:scripts": "0 — tsc --listFiles confirms both changed files are in the program, so measured not vacuous", "pnpm lint:root": "0 — 32 pre-existing warnings, 0 errors; full scan, no narrowing declared", "pnpm check:control-bytes": "0 — 6472 tracked text files; plus manual grep -naP over both changed paths, no hits", "node scripts/check-changeset-presence.mjs": "0 — none owed (0 of 2 files are published source; root scripts/ publishes nothing)", "node scripts/check-governed-queue-guard.mjs --test both paths": "0 — NOT GOVERNED, with positive control AGENTS.md exiting 3 GOVERNED", "readers (A3)": ".github/workflows/skill-examples.yml invokes the gate as --build-filter, --self-test and bare — the notice's command line still matches; scripts/__tests__/check-skill-eval-tokens.test.ts names the gate in prose only and ran green in the directory sweep", "CI": "in_progress — reported at draft-PR time per the dispatch; not waited on" }, "deviations": [ "A2 partly falsified and refined: both sites do hold a `state`, but analyze() did not carry the workspace total out. Rather than hard-code a number or re-read the tree, analyze()'s return now includes the packageDirOf map it had already built to resolve neededPackages. One field, inside the named file surface, no behaviour change; the pin covers it with a temp-tree derivation test.", "origin/main moved mid-flight (65ce8c576 -> 0caacca37, PR #8054 landing app-shell/console vi.mock work plus scripts/check-vi-mock-inherit.mjs — disjoint from both of my files). Merged origin/main per A4 and re-ran every gate above on the merged head 3b26507ba; all readings in this report and in the PR body are from that head.", "PR left as draft and CI not awaited, per the dispatch's report-at-draft-PR rule. The diff is NOT on a governed surface (checked, with control), so the ordinary ready + merge-queue route applies whenever the PM decides." ], "mcp_calls": "3 — create_pull_request, pull_request_read (body read-back), add_issue_comment (this report). Issue body, claim comment and labels were read over the zero-quota web payload channel; no search_issues call was needed.", "open_questions": [], "out_of_scope_findings": [] }
Generated by Claude Code
ACCEPT — PR #8066, head
3b26507ba. One exportedscopedBuildNotice(named, total)called from both precondition sites with counts derived from state the gate already holds;--build-filterselection, scanner, judge and exit codes untouched; six-case pin with a proven must-fail leg. Flip and arming on CI convergence.domain:devx @ objectuiexecution seat, PM sessionsession_01FhBNJcLRZLe8M87VcUgpKr, R46, 2026-09-06T14:06Z. Report5559741692reviewed against GitHub and the tree, ⛔ not against its narrative.item reading (mine) PR shape draft ✅ · base main✅ · first lineFixes #7811✅ · other closing keywords in body / the dev's commit: 0 (#7795,#4846named without closers) ✅ · 2 files (+190/−0) ✅Gate diff ( 0caacca37..3b26507ba, read in full)analyze()returnspackageDirOf(the map it already built — one field, no re-read); newscopedBuildNoticewith a docblock in the #7795 shape;console.error(...)after the printed command at both sites (:1335regular,:1774self-test); no other line moves — selection logic, judge,EXIT_CODESunchanged ✅Test diff +134/−0, a newdescribewith sixits; zero existing lines removed ✅ · relative imports only ✅Ablation one call site removed on disk (blob 2b105219f → a6b6eb01b), pin exit 1 with two named failures, restored undertrap, blob back ✅Truth of the notice measured on the branch: filter names 10 of 40, turbo expands to 30 in scope, 29 of 40 hold a dist/afterwards — the sentence describes the observed leftover; the workflow header's refusal of the unfiltered build (objectui#4846 ruling) is cited, not asserted ✅Changeset root scripts/publishes nothing; presence script: none owed ✅ · NOT GOVERNED withAGENTS.mdas the positive control (exit 3) ✅ · nothing underskills/**or.claude/**✅Readers skill-examples.ymlinvokes the gate in the three forms the notice's command line matches; wholescripts/__tests__/111 files / 3333 tests ✅Report hygiene: 3 MCP calls; the body read-back over MCP could have been a REST read — recorded, not a rework.
Next: standing-down note for
Live E2E (informational)on the PR, wait for CI convergence on3b26507ba, flip ready, post-flip guard, arm auto-merge (squash), then the landing probe on re-fetchedorigin/main:scopedBuildNotice(inscripts/check-skill-examples.mjs= 3 (one definition, two calls),objectui#7811in the test = 1, control:scopedBuildNotice(incheck-doc-snippet-types.mjsunchanged. Card closes on merge;pm:dispatchedoff and assignee cleared in the same stroke.
Generated by Claude Code
Armed: PR #8066 (head
3b26507ba) flipped ready 14:18:55Z on all-green-but-the-base-red lane (28 checks, standing-down note5559749775, anchor #7990), post-flipGoverned Surface Queue Guardsuccess14:19:13Z, auto-merge (squash) enabled,added_to_merge_queue14:19:21Z (REST timeline). Landing stroke on MERGED per the ACCEPT5559749500:scopedBuildNotice(inscripts/check-skill-examples.mjson re-fetchedorigin/main= 3,objectui#7811in its test = 1, control:scopedBuildNotice(count incheck-doc-snippet-types.mjsunchanged; the card closes on merge (Fixes), thenpm:dispatchedcomes off and the assignee is cleared.
Generated by Claude Code
LANDED — PR #8066 merged 2026-09-06T14:34:18Z (queued 14:19:21Z). Verified on
origin/main295804a63by CONTENT, ⛔ not by the merge event.domain:devx @ objectuiexecution seat, PM sessionsession_01FhBNJcLRZLe8M87VcUgpKr, R46, 2026-09-06T14:35Z.reading expected got scopedBuildNotice(inscripts/check-skill-examples.mjs(one definition, two calls)3 3 objectui#7811inscripts/__tests__/check-skill-examples.test.ts≥ 1 4 control — scopedBuildNotice(incheck-doc-snippet-types.mjs, unchanged2 2 ✅ probe fires Card closed by
Fixes;pm:dispatchedcomes off and the assignee is cleared in the same stroke.
Generated by Claude Code
check-skill-examples.mjs在两处打印同一条「照闭包建包」的命令,和 objectui#7795 一样没有说这个闭包是裁剪过的:照着它敲的人得到的是一棵按「被判 examples 的 import 面」裁剪的树,而命令本身没有说这一点 —— 剩下的未建成包读起来像一次半失败的构建。
出处
由 objectui#7795 的实现析出。改
check-doc-snippet-types.mjs那一处打印时,git grep命中的另一处就是它。⛔ 没有在那张卡的 PR 里顺手改:#7795 的认领把 file surface 明确限定在scripts/check-doc-snippet-types.mjs,越界就是不可复核的蔓延。测量(工作树基于
origin/maina617bb8d3)scripts/check-skill-examples.mjs两个站点,都在「前提未满足」路径上,都以EXIT_CODES.couldNotRun返回:--self-test之外的常规路径(下一行印pnpm check:skill-examples)--self-test的 type-check 腿(下一行印node scripts/check-skill-examples.mjs --self-test)同一棵树上
node scripts/check-doc-snippet-types.mjs --build-filter点名 26 个包,packages/下共 40 个;check-skill-examples.mjs的 filter 是另一份集合,但形状相同。修法方向(方向,不是命令)
照 objectui#7795 落地的形状搬:在打印命令之下多印一段,说明该 build 是裁剪过的、留下的未建成包是设计的终态,并把「到底选了哪些包」委托给同一份 filter(给命令追加
--dry=text,读它的 "Packages in scope"),⛔ 不在别处再写一份会腐烂的包名清单。计数从脚本自己已经读到的数据派生。为它加一个能失败的 pin。⛔ 不要改
--build-filter的选包逻辑 —— 裁剪是那道门的设计意图。现状
和 objectui#7795 同类:这是人机工程缺口,今天不产生任何红。
本卡由实现 objectui#7795 的 os-dev 席位(session
session_01KbJQ1y1J12nZxYzFWhP8Q3)析出并立卡,未指派任何人,等 PM 分诊。Generated by Claude Code