Skip to content

docs(api): make the client-sdk packages.install example parse as a manifest - #18803

Merged
os-try-charles merged 2 commits into
mainfrom
claude/issue-18776-client-sdk-install-example
Sep 17, 2026
Merged

os-try-charles merged 2 commits into
mainfrom
claude/issue-18776-client-sdk-install-example

Conversation

@os-try-charles

Copy link
Copy Markdown
Collaborator

Fixes #18776

What was wrong

content/docs/api/client-sdk.mdx:337 — the client.packages fenced block on the SDK page an integrator reads before the README — showed:

await client.packages.install({ id: 'com.objectstack.plugin-auth', version: '1.0.0' });

Parsed against the contract that door itself declares — PackageInstallRequestSchema, whose manifest key is ManifestSchema (packages/spec/src/kernel/manifest.zod.ts:244) — the literal is refused twice:

invalid_value at [manifest, type]
invalid_type  at [manifest, name]

type and name are both required root manifest keys and both were absent, so the example fails when copied verbatim. Same kind as #18607, one page along.

The repair

Two required keys added, nothing else, in the key order the package's own published README uses for the same door (packages/client/README.md:247, landed by #18607) so the two copies of this example agree:

await client.packages.install({
  id: 'com.objectstack.plugin-auth',
  type: 'plugin',
  name: 'Auth Plugin',
  version: '1.0.0',
});

⛔ No schema was touched. This card is an example that is wrong, not a contract that is wrong, and the measurement below did not invert that.

Triage's escalation probe — the second deliverable

Triage attached a mandatory escalation condition: parse every install/bootstrap example across content/docs/api/**, and if more than this one is refused, the finding is not one broken example but a published-example surface with no gate.

Method (⛔ not an eye-pass). A throwaway AST probe over all 13 files of content/docs/api/**: ts/typescript/tsx fences are parsed with the TypeScript compiler API, every call site in the population below is located mechanically, and its argument literal is parsed against the contract that call site declares. An object member shape the reader does not model throws rather than passing quietly, and an empty population throws — a probe that measures nothing must not read as green.

door population contract it is parsed against
packages.install(<literal>) 1 PackageInstallRequestSchema (manifest: ManifestSchema)
packages.enable/disable/uninstall(<arg>) 3 the declared id: string
packages.list(<arg?>) 2 the declared filters?: { status, type, enabled }
new ObjectStackClient(<literal>) 4 ClientConfig, read out of packages/client/src/index.ts itself
defineStack(<literal>) 2 ObjectStackDefinitionSchema
shell fences pnpm add / npm install 2 the named workspace package exists and is not private
total 14 across 3 files

Positive control — the probe must catch the refusal we already know about, or it is not measuring this. It does:

BEFORE  tree /home/user/objectstack-18776-base @ 6de7a2d6e (origin/main at the branch point)
  population: 14 example(s) across 3 file(s)
  REFUSED: 1
    content/docs/api/client-sdk.mdx:337  [packages.install]
      -> invalid_value at [manifest, type]
      -> invalid_type at [manifest, name]

AFTER   tree /home/user/objectstack-issue-18776 @ fd887ab61
  population: 14 example(s) across 3 file(s)   (unchanged — the repair moved a verdict, not the corpus)
  REFUSED: 0

Verdict: exactly one refusal across content/docs/api/**, and it is the one this card names. The escalation condition is not met — nothing here re-grades the card or calls for the separate "published examples have no executability gate" carrier. Two things are reported rather than silently excluded:

  • content/docs/api/metadata-api.mdx:108 and :116 carry the install and publish request bodies as inline prose with an explicit ellipsis — { manifest: { id: "plugin-auth", name: "Plugin Auth", version: "1.0.0", ... }, ... }. They omit type, but the ellipsis is written in, they are not valid TS/JSON as printed, and nothing can be copied verbatim out of them. On this lane's boundary that is 不完整, not 错误 — outside the probe's parseable population and left alone.
  • content/docs/api/environment-routing.mdx:31 is a defineStack example whose manifest is an explicit // ...your manifest, objects, apis, etc. placeholder. It is accepted by ObjectStackDefinitionSchema as written (that key is optional), so it is a pass, not a waiver.

⛔ No gate was built, wired or modified. The card measured why three existing gates cannot see this class and recorded that wiring a census into a required gate is a maintainer's floor decision; this PR does not take that decision, and it deliberately does not extend #18607's README pin to this page for the same reason.

Verification

  • Gate families — node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derives 39 families for this change set (1 path). All 39 run on the final commit fd887ab61, each exit code captured before any pipe: 39 exit 0. --ran reconciliation: 39 derived, 39 run, 0 NOT-MEASURED, 0 UNRUN (a DERIVED zero).
    • Four of them first answered a prerequisite, not a finding — check:doc-formula-expressions, check:doc-security-posture and check:docs-transcript-drift exited 3 (@objectstack/lint / @objectstack/formula not built) and check:skill-examples exited 1 on the same shape (packages/client-react/dist holds no .d.ts). Built what each one named, re-ran, all four exit 0. check:skill-examples is the gate whose SDK_DOCS_PAGES population contains this page.
  • pnpm lint is CI's run; the local narrowing is measured, not skipped. ① The universe read from eslint's own config: every files: block in eslint.config.mjs names {ts,tsx,mts,cts,js,jsx,mjs,cjs} and zero of them name md or mdx. ② eslint --no-inline-config --format json content/docs/api/client-sdk.mdx reports 1 file, 0 errors, 1 warning — "File ignored because no matching configuration was supplied." ③ Invariance: neither projectService nor parserOptions.project appears in eslint.config.mjs, so type-aware linting is off and this diff cannot move the verdict on any untouched file — and the changed file is outside the linted set entirely.
  • check:pm-dispatch-gates is not in this change set's derived families (it is not reachable from a content/docs/** path), so its detached-run prescription does not apply here.
  • Merged origin/main at 9846f2763 before opening; no conflict, and nothing on main had touched this file since the branch point. Re-derived the families from the merged tree with main's newer scripts/pm/dispatch-gates.mjs: the same 39, no additions. Rebuilt spec / lint / formula / client-react after the merge and re-ran all 39 on the merge commit — the reading above is that run.
  • No same-file collision with fix(runtime,spec): the resume door asks the engine whether a status-less exit is repairable #18792, which edits :767-783 of this file. Untouched here.

Changeset — measured, not defaulted

skip-changeset. The criterion is whether anything published moves.

⇒ this diff publishes nothing from any released package.

Acceptance notes

🤖 Generated with Claude Code

https://claude.ai/code/session_017ef78bLdybu3AffehKkhfk


Generated by Claude Code

…manifest

`content/docs/api/client-sdk.mdx` showed

    await client.packages.install({ id: 'com.objectstack.plugin-auth', version: '1.0.0' });

Parsed against the contract that door declares — `PackageInstallRequestSchema`,
whose `manifest` key is `ManifestSchema` — the literal is refused twice:
`invalid_value` at `[manifest, type]` and `invalid_type` at `[manifest, name]`.
Both keys are required on the root manifest and both were absent, so the
example fails when copied verbatim.

The repair adds the two required keys and nothing else, in the same key order
the package's published README uses for the same door.

Claude-Session: https://claude.ai/code/session_017ef78bLdybu3AffehKkhfk
Co-authored-by: Claude <noreply@anthropic.com>
@os-try-charles os-try-charles added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 17, 2026 — with Claude
@github-actions github-actions Bot added size/xs documentation Improvements or additions to documentation labels Sep 17, 2026
@os-try-charles
os-try-charles marked this pull request as ready for review September 17, 2026 22:03
@os-try-charles
os-try-charles added this pull request to the merge queue Sep 17, 2026
Merged via the queue into main with commit e7eb4e9 Sep 17, 2026
38 checks passed
@os-try-charles
os-try-charles deleted the claude/issue-18776-client-sdk-install-example branch September 17, 2026 22:28
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/xs skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants