Skip to content

skills(objectstack-ui): pages.md states the embed scope os build enforces — this package or a declared dependency - #27304

Merged
os-zhuang merged 2 commits into
mainfrom
claude/issue-27209-pages-embed-scope
Oct 28, 2026
Merged

os-zhuang merged 2 commits into
mainfrom
claude/issue-27209-pages-embed-scope

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #27209
Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:skills/objectstack-ui/rules/pages.md〈Inline metadata views〉里 os build 的 lint 句,从「被引用项必须存在于本包」改为「必须存在于本包,或本包在 manifest.dependencies 里声明的包(仅直接依赖、单向)」,其余不合范围的引用照旧构建失败并点名所判范围;另加 @objectstack/skills 的 patch changeset(skills/** 随该包发布)。
  • 为什么改:平台已按 docs/metadata-embed-ref 的新范围判定嵌入(本包 + 声明的直接依赖),技能文档仍教更窄的规则,会让 AI 作者为了嵌入而重复声明元数据;技能面要陈述平台强制的闭合规则。
  • 风险与回滚:零运行时改动,只动一句技能文字与一份 changeset;回滚即 revert 本 PR。文件 token 读数 5691 / 上限 5692(余量 1),后续在该文件再加字须先删字。
  • 先看:skills/objectstack-ui/rules/pages.md 第 397–401 行(唯一风险 hunk:措辞是否与 packages/cli/src/utils/collect-docs.ts lintMetadataEmbeds 的范围一致);其次 .changeset/27209-pages-embed-scope.md。
  • 两分钟验证:node scripts/check-skills-token-ratchet.mjs 应打印 pages.md is 5691 tokens (ceiling 5692; headroom 1) 且退出 0;pnpm --filter @objectstack/skills build 应报 93 个文件 byte-identical 复制。
  • 需要你做的:skills/** 为 Tier H 受管面,本 PR 保持 draft,由 GOVERNED_APPROVERS 账号 approve 后由席位落地。

What changes

One sentence in skills/objectstack-ui/rules/pages.md (〈Inline metadata views — the metadata fence (ADR-0051)〉), worded from lintMetadataEmbeds / embedScope in packages/cli/src/utils/collect-docs.ts and its collect-docs.package-docs.test.ts cases:

Before:

the referenced object-rule / flow / permission set must exist in this package — a dead same-package reference fails the build (same posture as a broken link). At render time a missing or forbidden reference degrades to a placeholder, never a crash.

After:

the referenced object-rule / flow / permission set must exist in this package or one it declares in manifest.dependencies (direct dependencies only; one-way) — anything else fails the build, naming the scope it judged (same posture as a broken link). At render time a missing or forbidden reference degrades to a placeholder, never a crash.

The code this states: the lint's sources are the owner's body plus declaredDependencyIds(body) resolved against the artifact's packages (direct declarations only; a declared package does not reach back — pinned by the test a declaration is one-way: the declared package does not reach back), and the refusal text names this package or this package or its declared dependencies (…). Links are a different rule and still resolve artifact-wide (lintDocs against artifactNames); that sentence (pages.md line 335) is untouched.

.changeset/27209-pages-embed-scope.md — @objectstack/skills: patch. The PM's dispatch assumed skip-changeset; measured against AGENTS.md Post-Task Checklist step 3 (skip-changeset is for a diff that publishes nothing from any released package) and packages/skills/package.json (@objectstack/skills ships dist/skills/**, a byte copy of skills/**, in its files), plus pr-automation.yml's own text (a skills/** change releases @objectstack/skills and never takes the label), a changeset is owed and the label is not applied.

Token ratchet (node scripts/check-skills-token-ratchet.mjs), pages.md: before 5667 / ceiling 5692 (headroom 25) at merge base fa5e7825; after 5691 / 5692 (headroom 1). Net +24 tokens, inside the headroom the merged tree had (the claim's 5680 / +12 figure was read at 5b5cff15; main had moved).

Tests

Pure docs + changeset diff; no test file changed, no ablation (nothing a test pins moved).

  • OS_VERIFY_LOCK_SLOT=issue-27209-skills-build bash scripts/pm/os-verify-lock.sh -c 'pnpm --filter @objectstack/skills build' at c2fb9eee — sync-catalog self-test: 9 cases pass; 93 file(s) across 11 skill(s) copied from skills/** into dist/skills and read back byte-identical; VERDICT command-exit 0; diff -q of the edited pages.md against packages/skills/dist/skills/objectstack-ui/rules/pages.md is empty.

Acceptance notes

  • pages.md:335 "broken same-package links fail the build" is NOT made stale by the embed-scope change: lintDocs resolves a same-prefix link against every name the artifact carries (resolvableNames = artifactNames, the cli: read package docs from each package directory under an ADR-0130 layout — the widening half of #18170, blocked on two contract questions #18431 C2 shape), a cross-prefix link is deferred to publish, and a dangling same-prefix link is still docs/broken-link. The in-place fix exemption's first condition (same defect class, made stale by the same merged change) fails, so the sentence is left as written. Noted, not filed: that link refusal's message still reads no doc named "…" exists in this package while the set it judged is artifact-wide — class b candidate against the lint header's own text, reach: os build on a composed artifact with a dangling same-prefix link; the dangling target also does not exist in that package, so the words are not false, only narrower than the scope judged; carrier: none.
  • The PM's "no changeset / skip-changeset" assumption was falsified by measurement (above); a patch changeset for @objectstack/skills is in this PR and no label is applied.
  • No Skills-docs: line: the kind is none and there is no (narrowing) arm.
  • Harness attribution: the first commit on this branch was amended before any push to the model-free trailer pair (Co-authored-by: Claude + Claude-Session:), as the pre-push hook check:commit-card-trailers requires; no history on the remote was rewritten.

Verification

Local gate subset derived at c2fb9eee by node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (43 families) plus the claim's two spec checks; every exit code captured before any pipe; --ran reconciliation: 43 derived, 43 run, 0 UNRUN.

Green (exit 0, 40 of the 43 + 2 extras): check-adr-0087-registration (--base origin/main, --self-test), check-changeset-no-major, check-closing-keyword-parity (+ self-test), check-comment-mask-corpus, check-doc-route-spelling (--advisory, --self-test), check-dts-emitted --self-test, check-empty-changeset (--base, --self-test), check-skills-token-ratchet (gate: pages.md is 5691 tokens (ceiling 5692; headroom 1); self-test: 79 cases), ci/assert-turbo-remote-cache, ci/plan-test-core-shards, ci/prune-turbo-cache, pm/release-rehearsal-clone, release-pending-publish (self-tests), check:agent-test-spelling, check:changeset-gate-self-tests, check:ci-filter-parity, check:closed-ceremony-text, check:corpus-claim-drift, check:cross-package-test-inputs, check:doc-authoring, check:driver-memory-census, check:gitlink-declared, check:nul-bytes, check:pm-changeset-deadline-census, check:pm-governed-merges, check:pm-skill-id-lint (104 files clean), check:published-files, check:refd-timer-probe, check:role-word, check:skill-compatibility, check:skill-frame-sync, check:skill-identifier-liveness, check:sourcemap-no-sources-content, check:watch-hint-literal, @objectstack/spec check:skill-docs, @objectstack/spec check:skill-refs.

NOT MEASURED locally (build-dependent; exit 3 PREREQUISITE NOT MET, no workspace build was run for a docs-only diff — CI's Lint & Repo Gates carries them): pnpm --filter @objectstack/lint run check:doc-formula-expressions (needs @objectstack/formula + @objectstack/lint built), pnpm check:dual-build-cjs-loads (112 packages without dist/), pnpm check:lean-entry-closure (@objectstack/objectql dist absent). pnpm check:dts-closure exited 0 but swept only the 1 built package (@objectstack/skills, which owes no declaration entry) — read as NOT MEASURED for the TypeScript packages, not as green.

Dogfood battery: n/a — no ! in the title and no (narrowing) arm.


Generated by Claude Code

…rces — this package or a declared dependency

The 〈Inline metadata views〉 build-lint sentence said a metadata fence's
referenced item "must exist in this package". docs/metadata-embed-ref judges
an embed against the package that ships the doc plus the packages it declares
in manifest.dependencies (direct only, one-way); the sentence now states that
closed rule. Patch changeset for @objectstack/skills, which ships skills/**.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017xRBcUi2qhP1eKRbZJ1Ze1
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:skills#1 · sunhaolin · session_017xRBcUi2qhP1eKRbZJ1Ze1

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: c2fb9eeecae07dbddeb2d615e5a1c6539e5eff07
Local-runs: none
Scope: skills/objectstack-ui/rules/pages.md + packages/cli/src/utils/collect-docs.ts, packages/cli/src/utils/collect-docs.package-docs.test.ts, packages/core (declaredDependencyIds), .changeset/27209-pages-embed-scope.md

① Derived judgments

  • (a) TRUE only for packages the artifact carries: embedScope (collect-docs.ts:1425–1434) resolves declaredDependencyIds(body) via bodyById (this artifact's packages) and drops any other id; a stack with no packages[] gets [[stack], []], its manifest.dependencies never read (test :830). Over-states — ④.
  • (b) direct only: TRUE — declaredDependencyIds (packages/core/src/artifact-packages.ts:196) is Object.keys(dependencies), no transitive walk.
  • (c) one-way: TRUE — deps come from the owner's body alone; test :779.
  • (d) fails the build: TRUE — each miss is severity: 'error' (:1057–1076); compile.ts:1002–1021 exits 1.
  • (e) names the scope: 3 of 4 — scope (:1024) is absent from the rule-name miss (:1066).
  • (f) broken-link posture: TRUE — docs/broken-link is error too (:898).
  • (g) render-time: unchanged, TRUE — metadata-viewer.tsx:118–155 failed/notFound render Placeholder; MarkdownImpl.tsx:148 falls back to pre.
  • Flat src/docs/: embedScope(flatOwner?.index) (:1439) = top level + manifest-named package + its carried deps; "this package" as the package the doc ships on is right. Link rule at :335 is lintDocs :883–905 against artifactNames, untouched — right to leave.

② Semver level

patch is right: @objectstack/skills (package.json files: ["dist", …], not private) ships skills/** via sync-catalog; AGENTS.md:1019–1021 keeps skip-changeset for a diff publishing nothing. Clause-②: no / Metadata-protocol: none (kind none → patch) line-initial in both bodies; Check Changeset green.

③ Boundary flags

  • open_question (report first line): A — post-stamped.mjs:468–477 refuses an unsigned body and stripSignatureLine skips one; check-half-states.mjs OS_DEV_REPORT_MARKER admits a leading signature.
  • Dev 1 (changeset over label): correct, per ②.
  • Dev 2 (+24 vs +12): the ceiling binds; 5691/5692 reproduced; accepted, the wording below lands at 5689.
  • Dev 3 (3 gates NOT MEASURED): accepted — Lint & Repo Gates success on the head at read time.
  • Dev 4 (trailers) and Dev 5 (43/40/3/0): accepted; the trailers are the model-free pair AGENTS.md requires.
  • Ratchet: "naming the scope it judged" (~8 tokens) describes a refusal, not what the author writes, and is 3-of-4 true — drop it; it pays for the fix (must-fix, in ④).

④ Design judgment

Card scenarios hold: a declared sibling's state machine builds (test :772), an undeclared sibling's is refused (:765); closed form, no "may". But the sentence teaches a capability the build does not deliver: a dependency declared on a package installed separately (ADR-0141 D3's other arm) is never searched — a single-package stack reads no dependencies, a composed one drops uncarried ids — so an author embedding an installed app's flow gets "does not exist in this package" (picklist-references.ts:45 only reports such deps; that lint-vs-render gap is its own card).
must-fix: replace pages.md:397–401 with exactly:

the referenced object-rule / flow / permission set **must exist in this
package or in a package of the same artifact that it declares in
`manifest.dependencies`** (direct only; one-way) — anything else fails the
build (same posture as a broken link). At render time a missing or forbidden
reference degrades to a placeholder, never a crash.

(22756 B → 5689/5692, headroom 3; longest line 76.)

Implemented-by: claude/issue-27209-pages-embed-scope
Reviewed-by: session_017xRBcUi2qhP1eKRbZJ1Ze1

VERDICT: FAIL

Seat note: review run by an isolated at-tier reviewer agent, adopted by the seat (domain:skills#1) at 2026-10-28T16:04Z; the patch round goes back to the original dev on the same branch and claim; a delta review of the fixing commit follows.

…artifact it declares; drop the scope-naming clause

Contract review must-fix: embedScope resolves declaredDependencyIds through
the artifact's own packages (bodyById), and a stack with no packages[] never
reads manifest.dependencies, so a separately installed dependency is never
searched; the rule-name miss carries no scope text. The sentence and the
changeset prose now say "a package of the same artifact that it declares in
manifest.dependencies (direct only; one-way)" and no longer claim the refusal
names the scope.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017xRBcUi2qhP1eKRbZJ1Ze1
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:skills#1 · sunhaolin · session_017xRBcUi2qhP1eKRbZJ1Ze1

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 60b713f64a2844b1dc6fa59a7a33a1ec5fc94caa
Local-runs: none
Scope: skills/objectstack-ui/rules/pages.md + packages/cli/src/utils/collect-docs.ts, packages/cli/src/utils/collect-docs.package-docs.test.ts, packages/core (declaredDependencyIds), .changeset/27209-pages-embed-scope.md

① Derived judgments

Delta since 6474059798 (one commit, c2fb9eee..60b713f6, 2 files, +5/−5):

  • (a) CLOSED — pages.md:397–401 at the head are byte-identical to the must-fix hunk; "a package of the same artifact that it declares in manifest.dependencies" now matches embedScope (collect-docs.ts:1425–1434, bodyById = this artifact's packages) and the single-package path ([[stack], []], test :830).
  • (e) CLOSED — "naming the scope it judged" is gone from the sentence; the 3-of-4 refusal text is no longer claimed.
  • (b) direct only, (c) one-way, (d) fails the build, (f) broken-link posture, (g) render-time sentence: unchanged from 6474059798, all TRUE; the render-time line is byte-unchanged in the delta.
  • Flat src/docs/ owner and the link rule at :335: unchanged from 6474059798 — right to leave.

② Semver level

Unchanged: @objectstack/skills: patch. The changeset at the head keeps the frontmatter and the line-initial Clause-②: no / Metadata-protocol: none; its title and body now say "a package of the same artifact … (direct only; one-way)" and no longer claim the refusal names the scope. Check Changeset green on 60b713f6.

③ Boundary flags

  • Token ratchet: the dev's 5689 / 5692 (headroom 3) is reproduced — 22756 B → ceil(22756/4) = 5689; longest line 76 cols.
  • Nothing else moved: git diff --stat c2fb9eee..60b713f6 = the two files only; git diff origin/main...60b713f6 is still the same two files (+14/−3), merge-base fa5e7825 unchanged; the fixing commit carries the model-free trailer pair.
  • Note, not a must-fix: the PR body's "After:" quote and its 5691 / 5692 readings are superseded; the seat refreshes those passages (the dev does not PATCH a PR body) and the declaration lines stay intact.
  • open_question and deviations 1–5: answered in 6474059798, unchanged.

④ Design judgment

Both card scenarios hold against the code (declared sibling of the same artifact builds, test :772; undeclared sibling refused, :765), and the sentence now also refuses what the build refuses: a dependency installed outside the artifact is excluded by the words, so no author writes an embed the build rejects or avoids one it accepts. Closed form — no "may", no tolerance. The lint-vs-render gap on outside dependencies (picklist-references.ts:45 reports, lintMetadataEmbeds refuses) remains a card of its own, not this PR's.
must-fix: none.

Implemented-by: claude/issue-27209-pages-embed-scope
Reviewed-by: session_017xRBcUi2qhP1eKRbZJ1Ze1

VERDICT: PASS

Seat note: delta review by the same isolated at-tier reviewer agent as 6474059798, adopted by the seat (domain:skills#1) at 2026-10-28T16:11Z.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:skills#1 · sunhaolin · session_017xRBcUi2qhP1eKRbZJ1Ze1

维护者速读(席位终稿,钉 head 60b713f6)

  • 改了什么:skills/objectstack-ui/rules/pages.md〈Inline metadata views〉里 os build 的 lint 句,从「被引用项必须存在于本包」改为「必须存在于本包,或同一产物内本包在 manifest.dependencies 里声明的包(仅直接依赖、单向)」,其余引用照旧构建失败;另加 @objectstack/skills 的 patch changeset(skills/** 随该包发布,AGENTS.md 清单第 3 步)。
  • 为什么改:平台已按本包 + 同产物内声明的直接依赖判定嵌入(PR fix(cli)!: docs/metadata-embed-ref judges a package doc against its package and declared dependencies #27204 落地的 docs/metadata-embed-ref),技能文档仍教更窄的规则,AI 作者会为了嵌入而重复声明元数据;技能面要陈述平台强制的闭合规则。
  • 风险与回滚:零运行时改动,一句技能文字加一份 changeset;回滚即 revert。该文件 token 读数 5689 / 上限 5692(余量 3)。
  • 先看:skills/objectstack-ui/rules/pages.md 第 397–401 行;措辞对照 packages/cli/src/utils/collect-docs.ts:1425–1434 的 embedScope(本包主体 + declaredDependencyIds 在本产物 bodyById 内能找到的包,单向)。
  • 两分钟验证:node scripts/check-skills-token-ratchet.mjs 打印 pages.md is 5689 tokens (ceiling 5692; headroom 3) 且退出 0。
  • 需要你做的:skills/** 是 Tier H 受管面,请 GOVERNED_APPROVERS(os-zhuang / hotlong,已由中继请审)之一 approve;批准在案后由席位落地(ready + auto-merge)。
  • 席位意见:ACCEPT。首版句子多教了一项平台不兑现的能力(对单独安装的包声明的依赖不在搜索范围),达档契约复核 FAIL 后同分支一轮补丁收窄为「同一产物内」,复核 PASS;changeset 归属正确。

席位核对

  • 形态:draft PR,目标 main,正文首行 Fixes #27209,Clause-②: no / Metadata-protocol: none 在 PR 正文与 changeset 正文各一份;assignee sunhaolin;两文件,两个 commit(c2fb9eee 初版、60b713f6 补丁)。
  • 前提实测:origin/main 上 collect-docs.ts:1425 embedScope = 包主体 + declaredDependencyIds(body) 经 bodyById 解析出的同产物包(未携带的 id 丢弃;无 packages[] 的栈返回 [[stack], []]);测试 a declaration is one-way;旧句「must exist in this package」在合并基 fa5e7825 仍在。
  • 门禁 check-runs(钉 head 60b713f6,本席读数时刻见戳):36 check-runs: skipped 14, success 19, in_progress 3; not yet green: Lint · CI, release & engine gates, Plan Test Core shards, Type Check · consumer gates
  • 接受的偏差:① 本席「skills-only 取 skip-changeset」的假设被 dev 以 AGENTS.md 第 1020 行与 packages/skills/package.json files: [dist, …] 证伪,改为 patch changeset,正确;② 相对合并基净 +22 token,对席位预算 ≤ +12:预算读数过期(按旧 main 5680 算),棘轮余量 3 为真读数,本席接受;③ 三个 build 依赖门禁族本地 NOT MEASURED,由 CI Lint · docs & code guards 承担;④ 报告评论首行为席位署名、次行 os-dev-report(中继写工具要求,识别器跳过署名行)—— 答 dev 问题:A;⑤ PR 正文仍描述初版句子与 5691 读数,按 os-dev 规则 dev 不 PATCH 正文,以本评论与复核记录为准。
  • 范围外去向:pages.md:335 链接句经代码核对不过期(lintDocs 对产物全名集判同前缀链接),不改;docs/broken-link 报错文案比所判范围窄(class b 候选,无生产者改写请求)—— Acceptance notes,不立卡;复核 ④ 提到的「对单独安装的包声明的依赖,lint 不搜而渲染可达」的缺口 —— 不在本卡范围,记入轮报交分诊,本席不立卡;Skills-docs: 不欠(kind none)。
  • 落地条款:Tier H,等授权批准;批准后席位过落地前检(check-governed-merges.mjs --pr 27304、两 required job 绿、全 check 绿或预期 skip)再 ready + auto-merge。契约复核记录:FAIL 6474059798(head c2fb9eee)→ delta PASS 6474235904(head 60b713f6)。

@os-zhuang
os-zhuang marked this pull request as ready for review October 28, 2026 17:47
@os-zhuang
os-zhuang added this pull request to the merge queue Oct 28, 2026
Merged via the queue into main with commit b4eecd5 Oct 28, 2026
47 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-27209-pages-embed-scope branch October 28, 2026 18:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/s tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

skills(objectstack-ui): pages.md "Inline metadata views" should say an embed may name an item of a declared dependency (after #27090)

3 participants