Skip to content

fix(spec): list the five service-ai-studio tools the AI tool registry was omitting - #16844

Draft
claude[bot] wants to merge 1 commit into
mainfrom
claude/issue-16512-ai-studio-five-tool-names
Draft

fix(spec): list the five service-ai-studio tools the AI tool registry was omitting#16844
claude[bot] wants to merge 1 commit into
mainfrom
claude/issue-16512-ai-studio-five-tool-names

Conversation

@claude

@claude claude Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Clause-②: yes

Fixes #16512

PLATFORM_TOOLS_BY_PACKAGE['service-ai-studio'] now lists the five tools the cloud AI runtime registers that it had been omitting — get_authoring_rules, load_tools, open_record, test_flow, toggle_flow — inserted in the list's existing alphabetical order. Nothing else in the registry moves, and the module's maintenance-contract wording is untouched.

What this widens

PLATFORM_PROVIDED_TOOL_NAMES is the load-bearing half of skill.tools[] reference integrity under ADR-0109: the default third-party authoring path declares no tool records at all, so a skill.tools[] entry resolves against this registry, or against the materialised action_NAME family, or against nothing. While the five were absent, a skill naming any of them was reported by validate / lint as a fictional tool reference (ai-skill-tool-unresolved) — the precise failure the registry exists to end. Five previously-refused references become legal here; a name registered by nobody is still refused.

Premise re-measured on the current origin/main, with the positive control

Measured at f89812e4d in a dedicated worktree, in packages/spec/src/system/constants/platform-tool-names.ts. A searched zero without a positive control is not a reading, so both legs were run under the identical query:

name occurrences leg
test_flow 0 absence
toggle_flow 0 absence
get_authoring_rules 0 absence
load_tools 0 absence
open_record 0 absence
create_metadata 1 positive control
verify_build 1 positive control

The zero is the registry's, not the query's. None of the five was already present, so the card's premise still holds.

The alphabetical claim was verified, not assumed. Both groups were in fact sorted before this change (service-ai 6/6, service-ai-studio 24/24, machine-compared against their own sort), and the package's own shape test pins it — each group is sorted, so diffs stay reviewable.

Not measured here: the cloud side. objectstack-ai/cloud is outside this session's repository scope, so the "re-check the list against the current packages/service-ai-studio/src/plugin.ts" step was NOT MEASURED by me and is not claimed as done. The standing cross-repo reading is triage comment 5578936460 (2026-09-08T03:57Z), which measured both sides and found all five registered in cloud, each with its own tool file and its definition group imported by plugin.ts (FLOW_TOOL_DEFINITIONS, AUTHORING_RULE_TOOL_DEFINITIONS, LOAD_TOOLS_TOOL_DEFINITIONS, OPEN_RECORD_TOOL_DEFINITIONS).

The pin, and the ablation that proves it can fail

The behavioural pin lives in packages/lint/src/validate-ai-tool-references.test.ts, extending the existing suite rather than adding a parallel one — "refused" and "accepted" are that rule's verdicts, while the constant's own file can only pin the list's shape. It asserts the five now resolve, and carries its control in the same case: a sixth name shaped exactly like them and registered by nobody is still reported at skills[0].tools[5]. Without that control a universe widened until everything resolves would pass.

packages/lint resolves @objectstack/spec/system through exports to spec's dist/ with no vitest alias (it is a KNOWN_UNALIASED_TEST_IMPORTS pair), so each leg rebuilt spec and proved the mutation reached the artifact the suite consumes:

leg on-disk proof dist/ proof pin
mutation (five names deleted) anchors 5 → 0; blob aeaa3a67a differs from HEAD blob 275579d33 ablation-dist-preflight … --absent exit 0, marker absent from all 218 built files exit 1expected [ { severity: 'warning', …(5) }, …(4) ] to deeply equal [], the other 13 cases in the file still green
restore git checkout HEAD -- PATH (the file, named); blob back to 275579d33; whole-tree git status --porcelain empty ablation-dist-preflight exit 0, marker present in 4 built files exit 0 — 14 passed

Direction as predicted (turns red). Both legs ran from the committed state under a trap … EXIT INT TERM restore with absolute paths; nothing of the ablation is left in the tree.

Verification

Everything below was re-run at f7d762844, the head after the review amend described under Amend below; exit codes were captured by redirecting to a file first, never across a pipe. The test and typecheck rows are quoted from their run at ce12e1127, whose tree differs from this head by one word inside .changeset/ and by nothing a test, a typechecker or a build reads.

  • pnpm --filter @objectstack/spec test465 files / 12955 tests passed, exit 0.
  • pnpm --filter @objectstack/lint test102 files / 3565 passed, 5 skipped, exit 0 (its dependency closure built first; without it 40 files fail to collect on missing sibling dist/, a pre-existing worktree state and not this diff).
  • pnpm --filter @objectstack/spec typecheck and pnpm --filter @objectstack/lint typecheck — exit 0 each, both test-layer debt ledgers held.
  • pnpm --filter @objectstack/spec check:generated — exit 0, all 15 generated artifacts up to date; nothing to regenerate (the export set is unchanged; only a const's value moved).
  • pnpm lint (repo-wide eslint . --no-inline-config) — exit 0 in 98s. No narrowing, so none is claimed.
  • The derived gate families: node scripts/pm/dispatch-gates.mjs --commands gave 76 commands for this change set; all 76 were run and reconciled with --ran, which reports 76 derived, 76 run, 0 NOT-MEASURED, 0 UNRUN.
  • Two of those 76 answered exit 3 / PREREQUISITE NOT MET and are therefore NOT MEASURED, not green: pnpm check:dual-build-cjs-loads and pnpm check:type-check-debt, both of which need a full monorepo build (pnpm build / the whole-workspace turbo build) that this worktree does not carry. Neither can be reached by this diff — no export is added, removed or renamed. CI builds fresh and measures them.

Amend — two review findings, one push

CI on the first head (ce12e1127) returned two reds, both about carriers rather than about the diff. Both were fixed in a single amend, so the branch still carries exactly one commit and the three-file diff is unchanged.

  1. Part-of PR must not also close its card — RULE 2 of scripts/check-partof-closing-keyword.mjs: no commit on the pull request may carry a card-relation trailer at all; the body is the only carrier of the relation. The commit message carried the closing trailer for this card. It was removed from the commit message only — it stays in this body, where it belongs, and the Co-Authored-By: and Claude-Session: trailers are untouched. Readings: --self-test exit 0 (92 cases), and the main leg driven with this PR real body and commit list exit 0carries no Part-of/closing-keyword contradiction … and its 1 commit message(s) carry no card-relation trailer. Control on the same leg with the pre-amend message: exit 1, so the instrument fires on this exact input.
  2. Check Changeset — the level axis: a clause-② declaration may not grade patch a package whose packages/*/src/** the PR moves, because a purely additive widening of a published surface takes at least minor. The changeset moved patch to minor; the declaration line and the needs:contract-review carrier were not touched, and the changeset prose is unchanged. Readings: node scripts/check-changeset-no-major.mjs --base f89812e4d exit 0, and re-run with this PR own event payload so the axis is really judged rather than skipped, exit 0LEVEL AXIS: this PR declares clause-② yes, and no package whose packages/*/src/** it moves is graded patch; carrier and declaration line both read.

The amend was a message-only rewrite for finding 1 (tree hash identical across it, 6cac29427 before and after) plus the one-word changeset change for finding 2. Every derived gate family was then re-run on the new head — 76 derived, 76 run, same two prerequisite gaps and nothing else — and the repo-wide pnpm lint re-run at f7d762844, exit 0.

Downstream — named, not acted on

  • objectstack-ai/cloud#1995 carries Blocked-by this card and is the half that stops the drift recurring: it makes the conformance test derive the union from what plugin.ts registers instead of restating it. Re-copying the list correctly today only resets the clock, which is accepted — this PR is the data half. Not touched here.
  • objectstack-ai/objectui#7481's tool-step labels read this registry; all five currently fall through to an English title-caser mid-Chinese conversation, and that card holds a hand-written workaround list meant to empty once this lands and the pin moves. Not touched here.
  • The card keeps pm:blocking; no downstream card was edited, relabelled or moved out of its open state.

验收备注

One observation, noted and deliberately not filed — it is a documentation nit, and acting on it is outside this card's ruled scope:

skills/objectstack-ai/SKILL.md:75-79 restates this registry rather than deriving it, and this PR makes three of its numbers stale: "the 30 statically-registered platform tools" becomes 35, "24 schema / metadata / package tools from service-ai-studio" becomes 29, and the citation platform-tool-names.ts:38-82 becomes 38-87. Verified that nothing checks them: no gate reads those numbers, check:skill-docs and check:skill-refs are both green on this diff, and the passage itself already tells the reader "Read that file for the exact set", so the count is a summary and not the authority. It was left alone on purpose — skills/** is a governed surface carrying its own line and token ratchets, and editing it would convert this PR's landing path from an at-tier contract review to a governed human merge, which this card's ruling does not authorize. It is the same restate-instead-of-derive shape the cloud half addresses, one repo over. 承接者: the domain:spec seat, at this PR's contract review — it owns packages/spec and its published skill docs and is already reading this diff.

No other out-of-scope finding. The test_flow hits elsewhere in packages/ are service-automation's flow fixtures, unrelated to tool names.

Landing

⛔ Draft on purpose. needs:contract-review is on both the card and this PR. Do not flip out of draft, do not enqueue, do not arm auto-merge — the seat is arranging an at-tier contract review.

Authored by Claude Code in session session_016N6xmWt5hYm94ffVEwGH8x.


Generated by Claude Code

@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

6 anchor(s) derived from 1 changed package(s); no hand-written page names any of them, so this run has nothing to listnot a clean bill of health. This check sees only pages that NAME a derived anchor: one that documents this change in prose, or enumerates it in an authoring dialect, names none and stays invisible to it on every run.

What this run could not see
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

Coarse fallback — 131 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json c5ea982d971cb2550d35a845694a6cbc2575ea52packageMentionDocs.

Which tree this was computed on

This run read content/docs from dab174f4e2d2d755302afe0ab111f7aa359eafe9 — the merge of head f7d76284421933afad4b0747e1f43d3c01754350 into base c5ea982d971cb2550d35a845694a6cbc2575ea52, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin dab174f4e2d2d755302afe0ab111f7aa359eafe9 && git checkout dab174f4e2d2d755302afe0ab111f7aa359eafe9
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin c5ea982d971cb2550d35a845694a6cbc2575ea52 f7d76284421933afad4b0747e1f43d3c01754350 && git checkout -B drift-repro c5ea982d971cb2550d35a845694a6cbc2575ea52 && git merge --no-ff f7d76284421933afad4b0747e1f43d3c01754350

node scripts/docs-audit/affected-docs.mjs --json c5ea982d971cb2550d35a845694a6cbc2575ea52

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

…omitting

`PLATFORM_TOOLS_BY_PACKAGE['service-ai-studio']` omitted five tools the cloud
AI runtime actually registers — `get_authoring_rules`, `load_tools`,
`open_record`, `test_flow` and `toggle_flow` — so under ADR-0109, where the
default authoring path declares no tool records at all, a skill naming any of
them resolved against nothing and was reported by `validate`/`lint` as a
FICTIONAL tool reference. That is the exact failure the registry exists to end.

Added in the list's existing alphabetical order (verified: both groups were in
fact sorted before this change, and the package's own shape test pins it).
Nothing else in the registry moves.

The pin lives in `packages/lint`, where "refused" and "accepted" are the
verdicts: the five now resolve, and a sixth name shaped like them and
registered by nobody is still reported — the control, without which the
widening pin cannot fail.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016N6xmWt5hYm94ffVEwGH8x
@claude

claude Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

Contract review — VERDICT: PASS WITH FINDINGS, no file correction required (at CONTRACT_REVIEW_TIER)

Read at 2026-09-08T10:51:00Z, bound to head f7d762844. Isolated contract-review-tier reviewer, read-only mandate, eleven rows.

Tier fuse (PM): 104 harness-stamped "model" values in the reviewer's transcript, all claude-fable-5-1, zero of any other model. ⛔ Its own TIER: line is not the fuse.

This review is the compensating control for a downgraded build. This card widens the accept set, 强制条款② made CONTRACT_REVIEW_TIER the required build tier, and this seat dispatched the dev at claude-opus-5 — below it. That was the seat's error, recorded on card #16512, and the reviewer was told to read the widening as if nobody had checked it rather than infer anything from the build tier.

The widening, measured

PLATFORM_TOOLS_BY_PACKAGE['service-ai-studio'] 24 → 29; PLATFORM_PROVIDED_TOOL_NAMES 30 → 35. What becomes legal is a skill.tools[] entry equal to one of the five, which at base produced an ai-skill-tool-unresolved warning from validateAiToolReferences (wired into REFERENCE_INTEGRITY_RULES, run by validate and lint).

⚠️ One imprecision in the PR body and changeset, non-blocking: they say a skill.tools[] entry resolves against the registry or the action_<name> family "and nothing else". collectToolUniverse actually seeds from three sources — those two plus stack.tools[].name. The claim holds only on the default path where stack.tools is empty. Worth a word if the head moves for another reason; ⛔ not worth a head of its own.

Rows

# Row Reading Finding
1 The widening MEASURED As above; consumer path confirmed in code (resolves() is universe.has(ref)). Secondary consumers move too: @objectstack/mcp now emits openWorldHint: false for the five (its pins are registry-derived, subset-direction, so nothing breaks), and objectui's tool-step labels read the same set.
2 Nothing ELSE widened MEASURED Machine diff of the constant: added exactly the five, removed none, service-ai group byte-identical, group keys unchanged, base order preserved as a subsequence, and the file with list lines stripped is identical base→head — docblock and maintenance-contract wording untouched.
3 Alphabetical order MEASURED Base groups sorted (6/6, 24/24), head sorted (6/6, 29/29), unique under JS default .sort() — which is what the spec-side pin enforces. The todo_write < toggle_flow trap is honoured (tod < tog).
4 The pin discriminates READ The pin's stack carries no tools and no actions, so the universe is exactly the registry ⇒ toEqual([]) cannot pass with the registry unchanged (five absent at base = five findings), and the control demands exactly one finding at skills[0].tools[5] naming archive_flow, which an over-widened universe would violate. No other name in the suite collides.
5 Changeset minor READ Right by the repo's own rule: an additive widening takes at least minor, and fix( may raise but never lower ⇒ the earlier patch refusal was correct. Every checkable claim in the prose holds.
6 The cross-repo premise NOT MEASURED ⚠️ See below — this is the one live condition.
7 The reverse risk READ Per name: get_authoring_rules and open_record carry runtime-grade evidence (objectui's AiChatPage.tsx:1518 handles the open_record hand-off; a live zh transcript rendered Get authoring rules); load_tools, test_flow, toggle_flow rest on two independent static observers with no contrary evidence. None looks fabricated. The only way one becomes a legalised fiction is a cloud rename after 03:57Z — row 6.
8 Scope MEASURED Exactly three files, 43 insertions, 0 deletions, one commit. The documentation label is the labeler matching the changeset .md, not a docs file.
9 Releases / governed paths MEASURED 0 of 3 diff paths match the register's own five globs; positive control: every one of those paths exists in the head tree (10 / 139 / 42 / 47 / 1 / 1 entries), so the zero is the diff's.
10 The SKILL.md staleness left unfixed READ Leaving it was rightskills/** is governed and one path hit makes the whole diff human-merge-only, which would have displaced this very review. Classified a documentation nit, not defect class (a)/(b)/(c): the passage subordinates its numbers to the file and nothing in the tree reads them. ⚠️ Two aggravations: the passage was already stale before this PR (its validate-ai-tool-references.ts:148-171 citation points past collectToolUniverse, now 144-164), and after landing it reads 30/24 against 35/29.
11 CI NOT MEASURED PM-held gate — read once for metadata only, not polled, no timer, no watcher.

⛔ The one condition that gates merging, and it cannot be met from this repository

Triage acceptance term #1 required the list to be re-read against cloud's plugin.ts at the moment of landing. objectstack-ai/cloud is out of this session's repository scope, so neither the dev nor the reviewer could meet it, and ⛔ 「仓不可达 ⛔ 不当查过了干净」.

⇒ Filed as #16852, with a named reader (a session scoped to objectstack-ai/cloud) and the two questions reduced to their smallest form: are the five still registered under exactly these spellings, and has a sixth static tool appeared since 2026-09-08T03:57Z. ⚠️ This PR does not enqueue until that comes back, because the failure direction of a wrong name here is that a genuinely fictional tool reference becomes legal.

What is already established is on that card: triage's direct cloud reading at 03:57Z, plus objectui#7481 as an independent second observer naming exactly these five.

Disposition


Generated by Claude Code

Copy link
Copy Markdown
Contributor

Contract review (CONTRACT_REVIEW_TIER, isolated seat) — PR #16844 @ f7d762844

Verdict: ACCEPT, conditional on CI converging green — at the time of this read 8 check runs are still in_progress (Test Core 1/6–6/6, Type Check · workspace, Lint & Repo Gates); 24 success, 3 skipped, 0 failures. Read as the compensating review for a below-tier build (card comment 5583508085: dispatched at claude-opus-5 against a CONTRACT_REVIEW_TIER mandate) — so the widening was read from the diff, not trusted from the build tier. Everything below was verified against refs/review/16844 and origin/main in this seat's own checkout, not taken from the PR body.

Ruling implemented: yes, exactly. The authorising text is the triage on card #16512 by @os-zhuang (MEMBER, comment 5578936460, 2026-09-08T03:57Z). It carries no literal ## Ruling recorded heading — the ruling section is headed ### 裁定:范围就是你写的那样,⛔ 一个字都不多 and reads verbatim:

  • ✅ 在 'service-ai-studio' 数组里按现有字母序加五个名字。(字母序确认:现数组严格升序,五个的插入位是 get_authoring_rulesget_active_packageget_metadata_schema 之间、load_toolslist_packagesmodify_field 之间、open_recordmodify_fieldpropose_blueprint 之间、test_flowtoggle_flowsuggest_buildertodo_write 之间 —— ⚠️ 注意 todo_writetoggle_flow 的相对次序,todo_write < toggle_flow。)
  • ⛔ 不重构注册表、⛔ 不改一致性契约的措辞。
  • 不做 cloud 那半(让一致性测试从 plugin.ts 自己的 toolDefs 拼接推导而不是重述)—— 那是 cloud#1995,且它才是让这件事不再复发的那一半

Dispatch/claim: comment 5582584428 (domain:spec execution seat, session session_016N6xmWt5hYm94ffVEwGH8x, branch claude/issue-16512-ai-studio-five-tool-names). The triage's own insertion map has one slip — it puts test_flow/toggle_flow both "between suggest_builder and todo_write" while also (correctly) noting todo_write < toggle_flow; the diff follows the sort, not the slip: test_flow before todo_write, toggle_flow after it.

Verification (numbered against the brief)

  1. Registry change. git diff f89812e4d..f7d762844 -- packages/spec/src/system/constants/platform-tool-names.ts is exactly five + lines: get_authoring_rules, load_tools, open_record, test_flow, toggle_flow. Group count 24 → 29 (service-ai untouched at 6, so PLATFORM_PROVIDED_TOOL_NAMES 30 → 35, i.e. N+5 as the ruling's acceptance item 2 requires). Machine-checked with LC_ALL=C sort -c: sorted, 29 unique. The docblock (maintenance contract, lines 28–31) is byte-identical. No other registry line moves.
  2. Files vs merge-base (f89812e4d): 3 files / +43 / −0 — the registry, packages/lint/src/validate-ai-tool-references.test.ts, .changeset/ai-studio-five-registered-tool-names.md. One commit on the branch. Governed paths touched: none (docs/adr/**, .claude/**, skills/**, AGENTS.md, CLAUDE.md, content/docs/releases/** all absent from the diff; Governed Surface Queue Guard green). The SKILL.md staleness the body reports is real — see F1.
  3. Clause-② from code. packages/lint/src/validate-ai-tool-references.ts collectToolUniverse() seeds the universe from PLATFORM_PROVIDED_TOOL_NAMES (a flat Set of the groups), so the accept set widens by exactly the five and by nothing else; a name registered by nobody still falls through to ai-skill-tool-unresolved. A second in-repo consumer also widens: packages/mcp/src/mcp-server-runtime.ts:303 stamps openWorldHint: false on any name in the set, so the five MCP-bridged tools change observable annotations — the changeset's claim about @objectstack/mcp is accurate, and this is one more reason the level is minor, not patch. The mcp bridge test derives its expectation from the set ([...PLATFORM_PROVIDED_TOOL_NAMES].sort()), so it widens with the registry rather than reddening. Cloud side: NOT MEASURED in-repo, and not measurable from this seat either (objectstack-ai/cloud is outside the review scope); the standing reading is triage 5578936460, same day, which measured plugin.ts imports and the four tool files. See F2 for the judgement.
  4. Changeset. "@objectstack/spec": minor. Graded against the batch [WIP] Add query enhancements and advanced validation features #35 WHICH LEVEL prose in .github/workflows/pr-automation.yml:667-681"A purely additive widening of a published package's public surface (a new exported symbol on an index, a new accepted key or value) takes at least minor … a fix( that widens an index is therefore minor" — the five names are new accepted values on a published constant, so minor is the floor and the amend from patch was correct. No export is added/removed/renamed, nothing previously accepted is refused ⇒ no BREAKING banner and no ADR-0087 disposition owed. check:generated green (15 artifacts) is consistent: value moved, surface did not.
  5. Tests. The new case in validate-ai-tool-references.test.ts asserts the five resolve to [] and that a sixth look-alike (archive_flow — confirmed registered nowhere in packages/spec/src or packages/lint/src, and not under any PLATFORM_TOOL_FAMILY_PREFIXES) is still reported at skills[0].tools[5]. The positive assertion reddens if the five are removed (toEqual([]) against five ai-skill-tool-unresolved findings — matches the body's ablation expected [ … (5) ] to deeply equal []); the control keeps a fully-widened universe from passing. No .skip / .only / .todo / xit in the file. The spec shape test each group is sorted, so diffs stay reviewable (platform-tool-names.test.ts:52) still holds by the sort check in 1, and no name collides across owning packages holds by the uniqueness check. Searched the head tree for any other test pinning the registry's size or restating the list: none (toHaveLength(24|30) hits are unrelated fixtures in objectql/service-analytics/format-type).
  6. CI on f7d762844 (35 runs): success 24 — including Check Changeset (10:36:53Z) and both Part-of PR must not also close its card runs (10:36:20Z, 10:37:17Z), the two reds the amend fixed; skipped 3 (Build Docs, Console Pin Gate, Packed-tarball smoke); in_progress 8 (Test Core ×6, Type Check · workspace, Lint & Repo Gates); failure 0. mergeable_state: blocked — consistent with draft: true + required checks pending, not a conflict. Branch is 9 commits behind origin/main (merge-base f89812e4d, PR base c5ea982d9); nothing in those 9 touches the three files. Labels: needs:contract-review present on PR and card; auto_merge null.

Findings

  • F1 (follow-up card owed; not a rider on this PR). skills/objectstack-ai/SKILL.md:75-79 restates the registry — "the 30 statically-registered platform tools", "platform-tool-names.ts:38-82", "24 schema / metadata / package tools from service-ai-studio" — and this PR makes all three stale (35 / 38-87 / 29; I confirmed } as const; sits at line 82 on main and 87 on the head). Leaving it out of this PR is correct: the ruling is "⛔ 一个字都不多", skills/** is governed and would flip the landing path to a human merge. But a published skill telling third-party authors the wrong count is not nothing, and no gate reads those numbers (check:skill-docs/check:skill-refs are content-blind to them), so it will not self-heal. The body assigns it to "the domain:spec seat, at this PR's contract review" — that is this seat, and this seat's boundary is one comment: the landing seat owes a docs-only card for skills/objectstack-ai/SKILL.md (lane domain:skills), ideally changing the passage to derive-or-omit rather than re-pinning fresh numbers that will drift again.
  • F2 (accepted residual, named). Acceptance item 1 of the ruling — 「落地前按当刻的 cloud plugin.ts 重核名单」 — was not performed by the dev (declared honestly as NOT MEASURED) and cannot be performed by this seat. Landing on triage 5578936460 is acceptable here because (a) it is a same-day, two-sided measurement by the triage seat with a positive control, (b) the only failure mode is a sixth name registered in cloud since 03:57Z, which would leave the registry still-incomplete rather than wrong, and (c) the sequence's step 3 (cloud#1995, derive-not-restate) is the instrument that catches exactly that. The repo:cloud seat doing the .objectstack-sha bump should re-run the diff against plugin.ts at that moment and, if a sixth exists, file it as a new spec card rather than reopening this one.
  • F3 (info). The changeset is the PR's input to the release notes; content/docs/releases/** is untouched, as required.
  • F4 (info, already handled elsewhere). The --force-with-lease amend vs AGENTS.md §3 conflict is filed as AGENTS.md §3 forbids force-push unconditionally, but check-partof-closing-keyword RULE 2 can only be satisfied by rewriting a commit message — a dev hit both today and had to be told which one wins #16851 by the dispatching seat; tree hash 6cac29427 is identical across the rewrite, so it has no bearing on this diff.

Maintainer-only merge: yes. Per the downgrade route recorded on the card (5583508085: 「降档施工只经契约复审档复核到达维护者」), this PR reaches main only by a maintainer's hand after this review — no enqueue, no ready-flip, no auto-merge by the seat. Precondition: the 8 pending runs finish green; if any Test Core shard reddens, treat this verdict as void and re-read the failure before landing.


Generated by Claude Code

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 protocol:system size/s tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PLATFORM_TOOLS_BY_PACKAGE['service-ai-studio'] is missing five registered tools, so a skill naming any of them reads as fictional to validate/lint

2 participants