Skip to content

docs(skills): point two published member counts at their declarations instead of numbers (objectui#12588) - #12591

Merged
os-zhuang merged 3 commits into
mainfrom
claude/issue-12588-guide-member-count
Oct 16, 2026
Merged

os-zhuang merged 3 commits into
mainfrom
claude/issue-12588-guide-member-count

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #12588
Clause-②: no

What changed

Two published skill guides each made a claim about an interface that the code does not bear out. Each is replaced with what the code says, and no count stands in for the old numbers.

  1. skills/objectui/guides/data-integration.md, in the caveat above the teaching fence of the DataSource interface section (one line):
    • before: "the published DataSource has 38 members and the excerpt is what makes this section readable"
    • after: "data.ts lists every published DataSource member and the excerpt is what makes this section readable"
  2. skills/objectui/guides/testing.md, in the "Auth provider testing" example:
    • The comment named a count and a wrong reach. Before: "AuthClient declares ~38 methods and the provider reaches ONE of them on this path." After: "Of every method AuthClient declares in packages/auth/src/types.ts, this path reaches getSession on mount and listOrganizations once a user is set; an empty list ends the organization load there."
    • The stub now covers both members it names. It gains listOrganizations, typed against AuthClient['listOrganizations'] the way getSession already is, and resolving to an empty list.
    • The line "This is the shape @object-ui/auth's own AuthProvider.test.tsx uses." is dropped. That file's createMockClient stubs its members with untyped vi.fn(), so it does not check a stub's resolved value the way this example does (measured below). The file is also not one a reader of the published guide can open.

The DataSource fence is still a deliberately simplified teaching copy, and the same paragraph still names packages/types/src/data.ts as the real declaration. The auth example still teaches the same typing discipline: each stub is typed against its own AuthClient member, and the widening happens once, in a named place.

No number stands in for either old one. A count goes stale every time a member is added or retired, and that is how both of these went wrong. The data-integration wording takes the shape PR #12586 already gave the optional-member sentence of the same section ("data.ts lists every optional member").

Why

  • The DataSource interface in packages/types/src/data.ts has 36 members at base 3eb3ec138a (TypeScript AST, overloads counted once): 6 required and 30 optional. The guide said 38. The section's later sentence "Six members are required" holds, so it is unchanged.
  • The AuthClient interface in packages/auth/src/types.ts has 39 members, all function-typed. The guide said about 38.
  • The auth example reached two members, not one. In packages/auth/src/AuthProvider.tsx, the mount effect's loadSession calls client.getSession(). Once a user is set, the "Load organizations once user is authenticated" effect runs refreshOrganizations, which calls client.listOrganizations(). On the old one-member stub that second call threw inside the try, and the provider reported it with console.warn. The example passed with that warning, not because one member was enough. An empty list returns from refreshOrganizations before getActiveOrganization or setActiveOrganization, and refreshActiveMember makes no client call while no organization is active.

Measured with uncommitted scratch files in packages/auth (deleted before the commit)

Run from the repo root with pnpm exec vitest run --maxWorkers=2 --reporter=verbose, under the shared verify lock, exit 0, Test Files 2 passed (2), Tests 3 passed (3). @object-ui/auth resolves to packages/auth/src through the root vitest alias.

  • The new fence, extracted verbatim from the guide into a test file, passes.
  • The new stub, with spies on console.warn and console.error: getSession calls = 1 · listOrganizations calls = 1 · console.warn calls = 0 · console.error calls = 0.
  • The old one-member stub still renders "Hello Alice", and console.warn is called with "[AuthProvider] Failed to load organizations:" and TypeError: client.listOrganizations is not a function.
  • Type level: tsc -p tsconfig.test.json in packages/auth exits 0, with --listFiles confirming it read the scratch files. It shows three things. The verbatim fence type-checks against the built @object-ui/auth. A createMockClient-style override, getSession: vi.fn().mockResolvedValue(42), is accepted. The fence's style, vi.fn typed with AuthClient['getSession'] resolving to 42, is refused (an @ts-expect-error line that would fail if it compiled).

Line budget (skills/**)

reading base 3eb3ec138a head 7b2bb22f71
skills/objectui/guides/data-integration.md 514 514
skills/objectui/guides/testing.md 370 370
package: every SKILL.md under skills/ (one file, skills/objectui/SKILL.md) 142 142

git diff --numstat against the base: data-integration.md +1/−1; testing.md +6/−6 (five comment lines rewritten in place, one stub line added, one line dropped).

Governed surface and changeset

  • skills/** is a governed surface (Tier H). node scripts/check-governed-queue-guard.mjs --test on the two files answers GOVERNED with exit 3, which is the code it uses for a governed diff that has no approval yet. This PR stays a draft until an authorized approver leaves an APPROVED review. After that, the claiming seat marks it ready.
  • No changeset. skills/ ships in no npm package, and no file under packages/ changed. node scripts/check-changeset-presence.mjs agrees ("no changeset is owed", exit 0), and node scripts/check-changeset-no-major.mjs exits 0.

Verification (local, at 7b2bb22f71)

Each exit code was captured to a file before any pipe. The quoted text is the verdict line the gate printed.

gate exit verdict line
node scripts/check-skills-paths.mjs 0 check-skills-paths: OK (89/90 stated path(s) resolve across 20 guide file(s); 1 baselined).
node scripts/check-skill-examples.mjs --self-test 0 check-skill-examples self-test: 60 cases pass
node scripts/check-skill-examples.mjs, after building its derived closure 0 Every marked skill example holds up against the built types. (18 of 18 ts fences judged, 70 JSON fences parsed; closure build 29 of 29 successful)
node scripts/check-skill-eval-tokens.mjs --self-test, then the main run 0, 0 Every must_contain token is taught by its own skill bundle.
node scripts/check-doc-json-fences.mjs 0 Every judged JSON node document on the scan surface passes the strict authoring face.
node scripts/check-control-bytes.mjs 0 check-control-bytes: OK (scanned 8984 tracked text file(s); skipped 93 binary).
node scripts/check-new-cross-file-line-citations.mjs 0 VERDICT new-cross-file-line-citations: 0 new citation(s)
node scripts/check-changeset-presence.mjs 0 No source or published contract of a released package changed in this range, so no changeset is owed.
node scripts/check-changeset-no-major.mjs 0 Every major is the synchronized one
node scripts/check-governed-queue-guard.mjs --test (the two files above) 3 GOVERNED (expected)

Skill-guide reader tests: 14 files. These are the test files that name data-integration, plus every test that walks skills/. I ran them with pnpm exec vitest run --maxWorkers=2 from the repo root, under the shared verify lock: Test Files 14 passed (14), Tests 464 passed (464).

The "Auth provider testing" fence carries no example-gate marker, so check-skill-examples does not judge it. The scratch run above is what measured it.

Acceptance notes

  • packages/auth/src/__tests__/AuthProvider.test.tsx: the comment in createMockClient says "AuthClient declares ~38 methods; this double implements the eight the provider reaches on the paths under test". Measured: AuthClient has 39. The double's literal names 7 members (signIn, signUp, signOut, getSession, forgotPassword, resetPassword, updateUser) plus the overrides spread, and the file never mentions listOrganizations. This is the same family as this card, but it is a test-file comment no user of the published guide reaches. Noted only: packages/auth is not edited here.
  • These are the other counts stated as a number in skills/objectui/** at 3eb3ec138a, each measured against the declaration it counts and cited by quoted text. All hold, and none is touched:
    • "Six members are required": DataSource has 6 required.
    • "the nine keys" and "those nine keys": QueryParams has 9.
    • "seven members": QueryResult has 7.
    • "Sixteen keys in total": the eleven on ComponentMeta plus the five RegistryComponentMetaExtras (11 + 5).
    • "The eleven control kinds": ComponentInputControlType has 11 arms.
    • "SIX keys are writable": ComponentInput has 14 members, 8 of them never tombstones.
    • "The seven props a widget author writes": the fence's own Pick has 7 keys.
    • "Those three gantt keys are the required ones": spec GanttConfigSchema has 3 required keys.
    • The six breakpoint keys: BreakpointName has 6 arms and BreakpointColumnMap has 6 members.
    • "Four text keys": spec EXPRESSION_BINDABLE_TEXT_KEYS_BY_COMPONENT has 4 distinct keys.
    • "default 1000 entries": ExpressionCache has maxSize = 1000.

No gate re-derives any of these counts, so each can drift the way the two changed ones did.

维护者速读(草稿)

改了什么
给使用者 agent 读的已发布技能指南里,有两处关于接口的说法与代码不符。本 PR 把它们改成代码实际的样子,不再写死任何数字。

  1. data-integration.md:原文「DataSource 接口有 38 个成员」,改为「完整的成员清单在 data.ts」。只改一行,仍是 514 行。
  2. testing.md 的认证测试示例:原注释说「AuthClient 大约有 38 个方法,provider 在这条路径上只用到其中一个」。实际用到两个:挂载时调用 getSession,用户登录后再调用 listOrganizations。注释现在直接点名这两个方法,示例里的测试替身也补上 listOrganizations,返回空列表。另外删掉一句「这和 @object-ui/auth 自己的 AuthProvider.test.tsx 写法一致」:实测不一致,而且读者也看不到那个文件。文件仍是 370 行。

为什么改
两个数字都是错的:实测 DataSource 有 36 个成员,AuthClient 有 39 个方法。数字本身也会过期。「只用到一个」也是错的:按旧示例写的测试虽然能通过,但会打出一条「组织加载失败」的警告,读者照抄就会把这个隐患带进自己的项目。新示例实测通过,而且没有任何警告。

风险与代价(含回滚)
只改文档和示例代码,不改任何包,不发 npm 包,不需要 changeset。风险极低:示例多了一行替身,读者照抄得到的是一个不报警告的测试。回滚只需 revert 对应的提交。

席位意见

你要做的
skills/** 属于受管面。请看一眼这两个文件的 diff,同意就留一条 APPROVED review,之后由席位翻 ready 并加入合并队列。不同意或想换措辞,在 PR 上留言即可。


Generated by Claude Code

… a number

The data-integration guide said the published DataSource has 38 members.
The declaration in packages/types/src/data.ts never bore that number out,
and every member added or retired moves it further. Replace the count with
a pointer to the declaration, in the shape the same section already uses
for its optional members, so the sentence cannot drift.

One line changed; the guide keeps its line count.

Claude-Session: https://claude.ai/code/session_01JZnppgHRp4sREcouhkQYDB
Co-authored-by: Claude <noreply@anthropic.com>
…f a number

The testing guide's auth-provider example said AuthClient declares ~38
methods. The declaration in packages/auth/src/types.ts has 39 at the branch
base, and every method added or retired moves the number again. Point at
the declaration instead, keeping the comment's teaching claim that the
provider reaches only one of those methods on this path.

Same shape as the DataSource sentence in the data-integration guide. One
line changed; the guide keeps its line count.

Claude-Session: https://claude.ai/code/session_01JZnppgHRp4sREcouhkQYDB
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet objectstack-fleet Bot changed the title docs(skills): point the DataSource member count at data.ts instead of a number (objectui#12588) docs(skills): point two published member counts at their declarations instead of numbers (objectui#12588) Oct 16, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: d6c74789acba697b441f0beea4403d2a60a017c3
Local-runs: none

PR #12591 (card #12588). Net diff against the merge base 3eb3ec138a: two files, one line each, skills/objectui/guides/data-integration.md and skills/objectui/guides/testing.md, matching the PR's file list. Current main (ae923ece22) touches nothing under skills/ since the merge base, so the net diff is the branch's two commits and nothing else. Both paths are governed, so the face is the governed-path one.

① Derived judgments

The data-integration.md line: right.

  • packages/types/src/data.ts declares export interface DataSource. It is the sole declaration under packages/types/src outside tests, it extends nothing, and packages/types/src/index.ts re-exports DataSource from ./data.js, so it is the published one. "data.ts lists every published DataSource member" is TRUE.
  • Measured at the head: 36 distinct members, 6 required (find, findOne, create, update, delete, getObjectSchema) and 30 optional, no overloads. The PR body's 36 is right; the removed 38 was false.
  • Teaching meaning kept: the caveat still says the fence is a simplified copy, and the same paragraph still points at packages/types/src/data.ts. No number stands in for the old one.

The testing.md line: the pointer half right, the reach half wrong.

  • packages/auth/src/types.ts declares export interface AuthClient, the sole declaration under packages/, extending nothing; packages/auth/src/index.ts re-exports AuthClient and AuthProvider. The pointer half of the line is TRUE. Measured: 39 members, all function-typed property signatures, none optional. The PR body's 39 is right; the removed ~38 was false. No number stands in for it.
  • ⛔ "the provider reaches ONE on this path" is FALSE at the head. Read in packages/auth/src/AuthProvider.tsx: the mount effect calls loadSession, which reaches client.getSession() (one). When that resolves with a user, the effect commented "Load organizations once user is authenticated" (deps user, enabled, isPreviewMode; the fence passes neither enabled={false} nor previewMode) calls refreshOrganizations, which reaches client.listOrganizations() (two). On the fence's one-member stub that call is a TypeError thrown inside refreshOrganizations' try, caught, and reported as console.warn('[AuthProvider] Failed to load organizations:', …). isLoading was already lowered in loadSession's finally, so "Hello Alice" renders and the example passes, with a warning, not because only one member is reached. refreshActiveMember returns before client.getActiveMember() (no active organization), so the count on this path is exactly TWO: getSession and listOrganizations.
  • The claim is pre-existing (the removed line said the same), but the PR rewrote the line and re-asserts the claim as checked: dev report round 2 ("Its teaching claim, that the provider reaches ONE member, is kept") and the PR body ("the stub needs only the one member the provider reaches"). Kept, yes; true, no. The card's whole class is a published skill sentence the code does not bear out, and this rewritten line still carries one, so it does not tell agents the truth.
  • Remedy, one line in place (keeps 370): say what is true. The session load reaches getSession only; the organization load that follows authentication reaches listOrganizations and absorbs its absence with a console.warn. Or stub listOrganizations too and say TWO. Correct the PR body sentence quoted above with it. For the seat, outside this diff: the unchanged next line "This is the shape @object-ui/auth's own AuthProvider.test.tsx uses" is loose too. createMockClient there stubs eight members and its own comment still says "~38 methods", the same family.

Spot-checks of the Acceptance-notes counts, each against its declaration at the head:

  • "Six members are required": DataSource has 6 required. Right.
  • "the nine keys" and "those nine keys": QueryParams in data.ts has 9 keys. Right.
  • "seven members": QueryResult has 7 (data required plus 6 optional). Right.
  • "Sixteen keys in total": ComponentMeta in base.ts has 11 and RegistryComponentMetaExtras in Registry.ts has 5. Right.
  • "The eleven control kinds": ComponentInputControlType has 11 arms. Right.
  • "SIX keys are writable": ComponentInput has 14 members, 8 typed never. Right.
  • The six breakpoint keys: BreakpointName has 6 arms and BreakpointColumnMap has 6 members. Right.
  • "default 1000 entries": ExpressionCache's constructor default is maxSize = 1000. Right.
  • Not re-derived here: the two spec-side ones (GanttConfigSchema, EXPRESSION_BINDABLE_TEXT_KEYS_BY_COMPONENT) and "The seven props a widget author writes" (the fence's own Pick).
  • No 38 or ~38 remains anywhere under skills/objectui/. Line budget as stated: 514, 370, 142.

Gates. Check-runs on the head, read at 2026-10-16T01:39Z: 30 success (Lint, Type Check, Repo Gates, Line Citation Gate, Governed Surface Queue Guard, the three Changeset gates, Build Docs, Build & E2E, Test (dist pins), all 16 Test shards and the Test aggregate, label), 3 skipped (dependabot and the coverage pair), and 1 still in progress, Spec Main Shape Gate. No failure. The earlier head b55c042e59's "Test" failure: its annotations say 15 shards did not report success, every one cancelled (shard 1 passed), and the aggregate exits 3 because it refuses cancelled shards by design (objectui#9499). The push of d6c74789ac superseded that run. A cancellation artefact, not a test result.

② Semver level

No changeset owed: skills/ ships in no npm package and no package source changed. Clause-②: no is on the claim and on PR body line 2. Changeset Declaration, Changeset Claim Re-read and Changeset Fixed Group Check all pass on the head. Right.

③ Boundary flags

  • R1 note, line 33 vs 34: the hunk @@ -31,7 +31,7 has three context lines before the change, so the number sat on line 34 and the sentence began on 33. Both citations were right about different things. Immaterial.
  • R1 note, provenance of 6479086867 NOT MEASURED (shallow boundary): the fix does not depend on it. No action.
  • R1 deviation, line addresses in the report comment rather than the PR body (AGENTS.md [WIP] Update documentation for project #11): accepted. The PR body carries none (checked), and the report pins each to 3eb3ec138a beside the quoted text.
  • R1 deviation, gates re-run in the resumed run: accepted.
  • R1 out-of-scope finding (AuthClient ~38): folded in by the seat in round 2. It is the line that fails above.
  • R2 deviation, the dev declined the PR-body PATCH and the seat sent it: confirmed. The PR timeline shows the retitle to "docs(skills): point two published member counts at their declarations instead of numbers (objectui#12588)" by the fleet bot after the round-2 report. The body is 8082 bytes, names both sentences in "What changed" and in 维护者速读, carries the testing.md row in the line-budget table, cites the head d6c74789ac, and keeps Fixes #12588 on line 1 and Clause-②: no on line 2. It matches the diff, except for its reach sentence, flagged in ①.
  • R2 note, origin/main moved to ae923ece22 with nothing under skills/: verified.
  • open_questions: none in either round. Nothing is escalated beyond ①.

Implemented-by: claude/issue-12588-guide-member-count
Reviewed-by: session_01JZnppgHRp4sREcouhkQYDB

VERDICT: FAIL

…nd stub both

The auth-provider example in the testing guide said the provider reaches one
AuthClient method on its path. It reaches two: getSession on mount, and
listOrganizations once a user is set. On the old one-member stub the second
call threw inside refreshOrganizations and was reported as a console.warn;
the example passed with that warning, not because one member was enough.

The comment now names both members, with no count, and the stub types
listOrganizations against AuthClient['listOrganizations'] the way getSession
already is, resolving to an empty list so the organization load ends there.

The line saying the example has the shape of the auth package's own
AuthProvider.test.tsx is dropped: that file's createMockClient stubs its
members with untyped vi.fn(), so it does not check a resolved value the way
this example does, and the file is not something a reader of the published
guide can open.

The guide keeps its line count: the dropped line pays for the stub's line.

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

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 7b2bb22f71574c15a8afc54e76fe300cff6deb07
Local-runs: none

PR #12591 (card #12588), round 3: does this head discharge the FAIL record 6206067543 at d6c74789ac and the rework ruling 6206085267? Net diff against the merge base 3eb3ec138a: two files, skills/objectui/guides/data-integration.md (+1/−1) and skills/objectui/guides/testing.md (+6/−6), matching the PR's file list; the branch's three commits and nothing else. origin/main (92c2a69769) touches nothing under skills/, packages/auth/, packages/types/src/data.ts or packages/types/src/index.ts since the merge base, so the code each sentence is judged against is the same at the head and on main. Both paths are governed, so the face is the governed-path one.

① Derived judgments

data-integration.md (unchanged since d6c74789ac): right.

  • packages/types/src/data.ts declares export interface DataSource, extending nothing. packages/types/src/index.ts re-exports DataSource from ./data.js. No other interface DataSource exists under packages/ at the head (the other three hits in the tree are a docs page, an example app's private mock and the guide's own teaching fence), and no package source carries a declare module '@object-ui/types' augmentation. So "data.ts lists every published DataSource member" is TRUE.
  • Measured at the head: 36 members, 6 required (find, findOne, create, update, delete, getObjectSchema) and 30 optional, no overloads. The PR body's 36 = 6 + 30 is right; the removed 38 was false. The section's later "Six members are required" holds.
  • No count stands in for the old one; the sentence takes the shape the same section's optional-member sentence already has ("data.ts lists every optional member"), as the card asked. No 38 or ~38 remains anywhere under skills/.

testing.md, the "Auth provider testing" fence: right, and it discharges the FAIL.

  • The pointer: packages/auth/src/types.ts declares export interface AuthClient, the sole declaration, extending nothing; packages/auth/src/index.ts re-exports it. 39 members, all function-typed. No count stands in for the removed "~38" or for the removed "ONE".
  • The reach, walked in packages/auth/src/AuthProvider.tsx at the head for a mount with the fence's props (client given, enabled defaulting to true, no previewMode), effect by effect in hook order:
    • client is memoised to the external stub, so createAuthClient is never called.
    • The rotation effect calls TokenStorage.subscribeRotation (not an AuthClient member) and re-runs loadSession only on a token rotation, which this path never produces.
    • The mount effect calls loadSession, which reaches client.getSession() — the one call on mount.
    • onAuthStateChange is not passed; authGateEvents.subscribe and SessionUserScope.adopt touch no client member.
    • The refreshActiveMember effect runs on mount and returns at !activeOrganization BEFORE client.getActiveMember(); its deps (client, enabled, isPreviewMode, previewMode, activeOrganization) never change on this path because activeOrganization stays null, so it never re-runs into that call.
    • The "Load organizations once user is authenticated" effect (deps user, enabled, isPreviewMode) runs once getSession has set user and calls refreshOrganizations, which reaches client.listOrganizations(). With []: setOrganizations([]), then the orgs.length guard is false for an empty list, so getActiveOrganization and setActiveOrganization are not reached and the function returns; finally resolves the two flags. No throw, no console.warn. user is set once (no other loadSession caller fires on this path), so this runs once.
    • useAuth reads context only; AuthConsumer renders state.
      So "this path reaches getSession on mount and listOrganizations once a user is set; an empty list ends the organization load there" is TRUE: exactly two members are reached, and no other AuthClient member is reached that the two-member stub would leave to warn or throw. Should the test's waitFor resolve before listOrganizations settles, the effect cleanup's cancelled flag suppresses the warn branch anyway.
  • The stub line: AuthClient['listOrganizations'] is declared as a zero-argument function returning a Promise of AuthOrganization[]. The repo pins vitest 4.1.10, whose vi.fn takes the function type as its one type argument, the way the existing getSession stub already uses it; mockResolvedValue then takes the awaited return, AuthOrganization[], and [] is assignable to it. The key is checked by the Partial-of-AuthClient literal, and the widening stays the single as unknown as AuthClient. Right. The dev's scratch tsc and vitest runs are consistent with this reading; they are reported, not re-run here.
  • The rest of the rewritten comment keeps the teaching claim, and it is true: the Partial literal checks the key, the typed vi.fn checks the signature, mockResolvedValue checks the resolved value. "ONCE" and "all three" name the single cast and the three checks the sentence itself enumerates — not member counts, so they cannot drift with the declaration.
  • Dropping "This is the shape @object-ui/auth's own AuthProvider.test.tsx uses": right. In packages/auth/src/__tests__/AuthProvider.test.tsx, createMockClient types only its overrides parameter as Partial of AuthClient; every stub is an untyped vi.fn().mockResolvedValue(...) and the literal is cast as unknown as AuthClient, so the discipline the fence teaches (each stub typed against its own member, resolved value checked) is not that file's shape. The sentence was untrue, and ruling 3 allowed the drop. The PR body's second reason — a reader of the published guide cannot open that file — is weak (the same comment now names packages/auth/src/types.ts, a repo path, as the guides do throughout), but the first reason carries the drop on its own.
  • Against record 6206067543: its one FAIL item was "the provider reaches ONE on this path". The head names the two members, stubs both, and closes the warn path. Discharged. Against ruling 6206085267: 1 (members named, no count) met; 2 (both stubbed, each typed against AuthClient[...], [], measured with no warn and the old stub shown warning) met per the round-3 report; 3 (shape line measured and dropped; packages/auth untouched; the test-file comment carried as an acceptance note) met; 4 (data-integration.md 514 and 514, testing.md 370 and 370, SKILL.md 142 and 142, read with wc -l over git show) met; 5 (body v3 on the PR) met, see ③.

PR body measured claims, spot-checked: 36 = 6 + 30, right; 39, right; "refreshActiveMember makes no client call while no organization is active", right; "an empty list returns from refreshOrganizations before getActiveOrganization or setActiveOrganization", right; numstat +1/−1 and +6/−6, right (six comment lines out; five comment lines and one stub line in); the line-budget table, right; "the fence carries no example-gate marker, so check-skill-examples does not judge it", right — that gate is opt-in by an HTML marker on the line directly above a fence, and the Pattern 6 fence has none (the opt-out note belongs to Pattern 7, a different fence); body line 1 Fixes #12588 and line 2 Clause-②: no, right; "no angle-bracket shapes", right (none in the body as read back).

Acceptance-notes counts, spot-checked at the head: "the nine keys" — QueryParams has 9 $-keys, right; "seven members" — QueryResult has data plus 6 optional, right; "SIX keys are writable" — ComponentInput has 14 members, 8 typed never, right; "The eleven control kinds" — ComponentInputControlType has 11 arms, right; "Sixteen keys in total" — ComponentMeta 11 plus RegistryComponentMetaExtras 5, right; the six breakpoints — BreakpointName has 6 arms, right; "default 1000 entries" — ExpressionCache's constructor(maxSize = 1000), right. The AuthProvider.test.tsx note: the createMockClient comment says "~38" and "eight"; the literal names 7 members plus the overrides spread, and the file never mentions listOrganizations, right. Not re-derived here: the two spec-side counts (GanttConfigSchema, EXPRESSION_BINDABLE_TEXT_KEYS_BY_COMPONENT) and the seven-prop Pick, which the earlier record also left; the diff touches none of them.

Gates. Check-runs on the head, read at 2026-10-16T02:03Z: 29 success — Repo Gates, Lint, Type Check, Build Docs, Build & E2E, Test (dist pins), all 16 Test shards and the Test aggregate, Line Citation Gate, Governed Surface Queue Guard, Changeset Declaration, Changeset Claim Re-read, Changeset Fixed Group Check, label; 3 skipped (dependabot and the coverage pair); 1 still in progress at that reading, Spec Main Shape Gate, which the diff (prose under skills/ only) gives nothing to judge. No failure.

② Semver level

No changeset is owed: skills/ ships in no npm package and nothing under packages/ changed. Clause-②: no stands on the claim and on PR body line 2. Changeset Declaration, Changeset Claim Re-read and Changeset Fixed Group Check are green on the head. Right.

③ Boundary flags

  • R1 note, line 33 vs 34: the hunk's three context lines put the sentence on 33 and the number on 34; both citations right, immaterial.
  • R1 note, provenance of 6479086867 NOT MEASURED (shallow boundary): the fix does not depend on it. No action.
  • R1 deviation, line addresses in the report comment rather than the PR body: accepted; the body carries none.
  • R1 deviation, gates re-run in the resumed run: accepted.
  • R1 out-of-scope finding (~38): folded in by the seat in R2; it is the fence this round repairs.
  • R2 deviation, the dev declined the PR-body PATCH and the seat sent v2: confirmed by the fleet bot's rename event on the PR timeline after the R2 report.
  • R2 note, origin/main moved with nothing under skills/: still true at 92c2a69769, and nothing under packages/auth/ either.
  • R3 acceptance note (AuthProvider.test.tsx's "~38 / eight" comment, and no listOrganizations in its double): measured true above. Ruling 3 forbade the edit, so that file's authenticated-session tests still run through the console.warn path the fence used to. Escalated to the seat as a candidate follow-up in this card's shape; no action in this PR.
  • R3 deviations: none. open_questions: none in any round.
  • PR body v3 is the body on the PR: 11302 bytes, cites the head 7b2bb22f71 in the line-budget table and the verification heading, carries the scratch-measurement section, states the two-member reach in "What changed", "Why" and 维护者速读, keeps Fixes #12588 on line 1 and Clause-②: no on line 2, and the PR's last update postdates the round-3 report. The title (renamed by the fleet bot in R2) names both files' scope. Body and title match the diff.

Implemented-by: claude/issue-12588-guide-member-count
Reviewed-by: session_01JZnppgHRp4sREcouhkQYDB

VERDICT: PASS

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

维护者速读

改了什么:给使用者 agent 读的已发布技能指南里,有两处关于接口的说法与代码不符,本 PR 把它们改成代码实际的样子,不再写死任何数字。两个文件的行数都不变:514 行和 370 行。

  • skills/objectui/guides/data-integration.md:原文「DataSource 有 38 个成员」,改为「完整的成员清单在 data.ts」。只改一行。
  • skills/objectui/guides/testing.md 的认证测试示例:
    • 原注释说「AuthClient 约有 38 个方法,provider 在这条路径上只用到一个」。实际用到两个:挂载时调用 getSession,用户登录后再调用 listOrganizations。注释现在直接点名这两个方法,不写数字。
    • 示例里的测试替身补上 listOrganizations,返回空列表。
    • 删掉「这和 @object-ui/auth 自己的测试写法一致」一句。实测不一致:那个文件的替身没有按成员加类型。

为什么改:

  • 两个数字都是错的:实测 DataSource 有 36 个成员,AuthClient 有 39 个方法。接口每增删一个成员,写死的数字就会再错一次。
  • 「只用到一个」也是错的。照旧示例写的测试虽然能通过,但会打出一条「组织加载失败」的警告,读者照抄就会把这个隐患带进自己的项目。
  • 新示例实测通过,没有任何警告。

风险与代价(含回滚):

  • 只改文档和示例代码,不改任何包,不发 npm 包,不需要 changeset。
  • 风险极低:读者少了两个本来就错的数字,换来可以自己核对的位置;示例多了一行替身。
  • 回滚:revert 本 PR 即可。

席位意见:建议批准。

  • 第一轮只改 data-integration.md 一句。第二轮按本席决定,把 testing.md 的同类计数一并纳入。
  • 本席发起的高档复审第一次判 FAIL(6206067543),指出「只用到一个」不属实。本席据此裁定返工(6206085267):点名方法、补齐替身。
  • 第二次高档复审 PASS(6206377097),CI 全绿。

你要做的:用 os-zhuang 或 hotlong 批准本 PR。批准后由本席翻 ready、加入合并队列。

席位核对

domain:ui seat 1 · session_01JZnppgHRp4sREcouhkQYDB · 2026-10-16T02:04Z · head 7b2bb22f71. This is the seat's ACCEPT for objectui#12588. Card pointer: ACCEPT → PR #12591 comment (this comment).

  1. Shape:
    • Draft, base main, assignee sunhaolin.
    • Line 1 is Fixes #12588, the body's only closing keyword. Line 2 starts Clause-②: no.
    • 2 files, +7/−7. No changeset: skills/ ships in no npm package, and check-changeset-presence agrees.
    • Tier H: both files are under skills/**, so the PR waits for a person.
  2. Premises measured:
    • DataSource has 36 members (6 required, 30 optional) in packages/types/src/data.ts. AuthClient has 39 in packages/auth/src/types.ts.
    • On this fence's mount path, AuthProvider reaches exactly getSession and then listOrganizations. An empty list returns before getActiveOrganization / setActiveOrganization, and refreshActiveMember makes no client call while no organization is active. This was walked effect by effect in 6206377097 ①.
    • The dev's scratch run, uncommitted: the new fence passes with 0 console.warn calls, and the old one-member stub warns [AuthProvider] Failed to load organizations: with a TypeError.
  3. Gates, read from check-runs on the head:
    • 33 runs: 30 success, 3 skipped (dependabot and the coverage pair), 0 failures. All 16 Test shards and the aggregate are green.
    • The earlier Test red on b55c042e59 was its 15 shards cancelled by the superseding push.
    • Contract review 6206377097: Served-tier: CONTRACT_REVIEW_TIER, the head sha matches, Local-runs: none, the independence pair is signed, PASS. It discharges the FAIL 6206067543 at d6c74789ac.
    • The dev's local gates at the head, all exit 0 (check-governed-queue-guard --test exit 3, GOVERNED, as expected): skill paths, skill examples, eval tokens, doc JSON fences, control bytes, new line citations and both changeset gates. The 14 skill-guide reader files ran 464 passed.
  4. Deviations accepted:
    • The AuthClient count was folded in on the seat's decision (round 2). It is the same class and the same package of guides.
    • The "shape AuthProvider.test.tsx uses" line was dropped (ruling 3, measured untrue).
    • The PR body was patched by the seat (v2, v3), because the dev writes it only at pr_create.
  5. Out of scope → Acceptance notes, ⛔ not filed:
    • packages/auth/src/__tests__/AuthProvider.test.tsx: createMockClient's comment says "~38 methods" and "the eight the provider reaches". The literal names 7, and the double has no listOrganizations, so that file's authenticated tests run through the provider's console.warn path.
    • It is a test file no user reaches, and its tests pass, so it does not clear the filing gate. A later edit to that file should carry the correction.
    • The other counts stated in skills/objectui/** were each measured true at the base, and spot-checked again in both records.
  6. Landing:
    • The PR stays draft until an approval from os-zhuang or hotlong (GOVERNED_APPROVERS). This act requests both and puts needs-user-decision on the PR.
    • After the approval, the seat runs the pre-landing checks, removes the label, and marks the PR ready with auto-merge through the queue.
    • ⛔ No seat approves.

Generated by Claude Code

@os-zhuang
os-zhuang marked this pull request as ready for review October 16, 2026 02:32
@os-zhuang
os-zhuang enabled auto-merge October 16, 2026 02:32
@os-zhuang
os-zhuang added this pull request to the merge queue Oct 16, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Pre-landing check · domain:ui seat 1 · session_01JZnppgHRp4sREcouhkQYDB · 2026-10-16T02:33Z

  • Approval: os-zhuang (GOVERNED_APPROVERS) approved at 2026-10-16T02:32Z (review 5542335595), on 7b2bb22f71. That is the head the seat record 6206393079 and the contract review 6206377097 judged. The head has not moved since.
  • CI on the head: 33 runs: 30 success, 3 expected skips, 0 failures. mergeable_state is clean.
  • The label: needs-user-decision comes off in the same stroke as ready and auto-merge. The merge closes objectui#12588.

Generated by Claude Code

Merged via the queue into main with commit 8415d9f Oct 16, 2026
34 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-12588-guide-member-count branch October 16, 2026 02:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants