skills(api): optimization flight — RestApiEndpointSchema example and other packages' anchors cut, the apiMethods rule stated once, http.server mount / error ledger / OCC taught (net −1,676 tokens) - #14448

Merged
os-zhuang merged 3 commits into
mainfrom
claude/issue-14304-skills-api-optimization
Sep 2, 2026
Merged

Conversation

@os-litant

Copy link
Copy Markdown
Collaborator

Part of #14304

The audit record this implements is posted verbatim on the card. Every claim written into the file was re-verified at source on this branch's base; the file:line for each is below. evals/README.md is untouched (API-H-01 is deferred to #14296 item 2), so the card stays open — that is why the first line is Part of, not a closing keyword.

Per-item: 落点 | before | after

finding落点 (before)beforeafter
API-E-01SKILL.md:117-146 — the leading os:check exampleauthored RestApiEndpointSchema "via the REST API plugin"deleted. The one live fact (auth is the flat public + permissions pair, no name/request/response field) folded into Auth Configuration
API-C-01:472-510 Datasource Configuration + Supported Driversa defineDatasource example and a 7-row driver tabledeleted → one pointer: objectstack-data rules/datasources.md, objectstack-platform Driver Selection Guide, and data/driver/config-registry.zod.ts for the id vocabulary
API-C-02:513-538 Inter-Service CommunicationIDataEngine contract prose + a marked block whose declare const kernel fabricated the hostdeleted → the section's slot now carries the API-F-02 construct; service resolution points at objectstack-platform rules/service-registry.md
API-C-03:458-468 Security Layersa 4-row table naming no authorable key + a callout restating its own Description columndeleted → one boundary line under Authentication & Authorization
API-D-01 + API-F-05 + API-A-03:316-366 Service Discovery / Healtha ServiceInfoos:check example, a JSON health body, /ready proserewritten to 3 lines — all three are response surfaces, nothing to author
API-D-02:383-396 Handler Statusa 3-row table its own callout neutralised ("nothing reads it at runtime")deleted; the now-single-child ## Dispatcher & Routing wrapper collapses into ## Dispatcher Error Codes
API-B-01:419-429third rendering of "no nested auth block" + an unmarked duplicate fragmentdeleted, merged into one sentence that also carries the API-E-01 fold
API-B-02 + API-G-01:203-209a second objectstack validate gate block 384 lines from the firstdeleted — the gate is stated once, in Verify your work, in the bundle-dominant os spelling
API-B-03:65-71, :283-313, :559-563the apiMethods primitives/derived rule stated 3×once. Callout → 3 lines; derived table drops the 3 rows with no route and no derivation (history/restore/purge keep a one-line mention); Best Practice 6 stops restating it
API-B-05:22-28preamble restating the frontmatter above the folddeleted
API-A-01:31-39 "When to Use This Skill"6 bullets, 3 of which misrouteSkill Boundaries table, matching objectstack-data / objectstack-query
API-A-02frontmatter :3-12promises "batch/versioning contracts""batch contracts"versioning.zod.ts has zero consumers outside a pin test
API-A-03:83-94three /meta client query-param contracts2 lines saying they are client contracts nothing declares
API-D-03:544-547, :556-558Best Practices 1 and 4deleted (1 duplicates :273 and is wrong for the carve-out; 4 names no key and no gate)
API-D-04:569-576Pitfalls 1, 2, 4deleted — FLS has no authorable spelling in the bundle, the page sizes match no platform constant, rate limiting is already the D6 rule
API-D-05:191-198two why-paragraphs after the carve-out ruledeleted, rule kept
API-F-04 + API-G-03:275-279environment-scoped routes + projectResolution, 0 usagesdeleted (takes the retired project gloss with it)
API-F-06:404-411two declared-but-unenforced realtime notesdeleted from the skill; filed as #14446
API-G-02:481defineDatasource imported from the root barrelmoot — deleted with API-C-01
API-F-01(add)gap — :164 named http.server with no exampleone table cellnew ## Code routes: mounting on http.server` section
API-F-02(add)gap — :548-555frontmatter promised "error envelopes"; the ledger rule was absentnew ## Error Envelopes & the Code Ledger (ADR-0112)
API-F-03(add):575-576"use optimistic locking (version field)", naming no spellingthe two real spellings, body-wins, 409 CONCURRENT_UPDATE

The three funded additions — every claim, with its source

1. http.server code mount — verified against all three shipping sites (examples/app-showcase/src/system/server/recalc-endpoint.ts:48-118, packages/plugins/plugin-sharing/src/sharing-plugin.ts:787-790, packages/plugins/plugin-approvals/src/approvals-plugin.ts:353-356).

  • dual lookup readServer('http.server') ?? readServer('http-server'), canonical first — sharing-plugin.ts:787-790, approvals-plugin.ts:353-356; both carry the same comment that http.server is "the ONLY name present on all provider paths".
  • kernel:ready, not later — packages/spec/src/contracts/plugin-lifecycle-events.ts:70-91: listen() is deferred to kernel:listeningbecause "route registration in Hono … seals the matcher the first time a request is matched"; recalc-endpoint.ts:110-112 hooks kernel:ready.
  • the handler signature — RouteHandler = (req: IHttpRequest, res: IHttpResponse) at packages/spec/src/contracts/http-server.ts:108-111; IHttpResponse.status(code): IHttpResponse at :77 (so res.status(200).json(…) chains); IHttpServer.post at :216.
  • the block is NOT os:check-marked, deliberately. See "Assumption 3" below — this is measured, not assumed.

2. ADR-0112 error-code ledgerpackages/spec/src/api/error-code-ledger.zod.ts:6-56 states the two tiers, "An unregistered code fails schema parse — which fails the envelope conformance suites — which fails CI", the framework-packages-only scope rule (#4805, maintainer ruling 2026-08-03 re-confirmed 2026-08-09), and the downstream composition. Functions re-located by content on this base: makeApiErrorSchema at packages/spec/src/api/contract.zod.ts:146, envelopeViolations at :215.

3. OCCpackages/rest/src/rest-server.ts:7710-7727 is the PATCH /api/v1/data/:object/:id route: If-Match header or expectedVersion body field, const expectedVersion = bodyVersion ?? ifMatchHeader (body wins), and the field is stripped from the write payload. The token semantics, the 409 and the "" refusal are the spec's own .describe() at packages/spec/src/api/protocol.zod.ts:2097-2102. CONCURRENT_UPDATE is registered at packages/spec/src/api/error-code-ledger.zod.ts:168 and pinned to 409 at packages/rest/src/rest-unclassified-fault-status.test.ts:230.

premise_false

API-F-01, the "getService is async" clause — the audit's premise is false and was NOT written. The real host contract is PluginContext.getService[T](name: string): T (packages/core/src/types.ts:36, doc comment @throws Error if service not found) — synchronous, and it throws. Measured on this base:

  • await ctx.getService in packages/plugins/**, excluding tests: 0 occurrences.
  • non-awaited ctx.getService( / ctx.getService[T](, same scope: 112.
  • the three app sites are ctx?.getService?.('manifest') with no await (packages/apps/{account,setup,studio}/src/index.ts:{60,55,68}).

The audit's evidence for "async" was recalc-endpoint.ts:52, which awaits — but that file's ctx is its own locally declared RecalcHostContext (:30-35) whose getService?: (name) => Promise<T> is a shim, not the host. That is precisely the defect API-C-02 was deleted for, so the skill states the true rule instead: getService is synchronous and throws, which is exactly why each name needs its own try and a() ?? b() in one try never reaches b.

The :532 "fix or unmark" item needs neither — the block is deleted with API-C-02, so no marker survives to prove or disprove anything.

PM assumptions — all six measured

#assumptionverdict
1skills/objectstack-api/** byte-identical a59f78d ↔ baseHOLDSgit diff a59f78d 96b627d1 -- skills/objectstack-api/ is empty; every audited span matched by content
2the frontmatter edit forces regeneration of BOTH generated filesHOLDScheck:skill-docs red on both before gen:skill-docs, green after; the .mdx pulled 20 docs-family gates into the union, re-derived and run
3the real PluginContext is unreachable from the os:check skills surfaceHOLDS, measured directly.SURFACES[0] resolves resolutionDir/selfPackages = packages/spec only (packages/spec/scripts/check-skill-examples.ts:526-532). Probed it: a temporary marked block importing PluginContext from @objectstack/core fails TS2307: Cannot find module '@objectstack/core'. Probe reverted and proven byte-identical (worktree blob hash == HEAD blob hash, git diff HEAD empty). ⇒ the F-01 block stays unmarked rather than earning a marker with a fabricated stand-in
4RestApiEndpointSchema 0 consumers · no plugin-rest-api package · no endpoints keyHOLDS — 0 hits outside packages/spec/src/api/plugin-rest-api* (positive control: the same grep for ApiEndpoint returns many); ls packages/plugins/ | grep -i rest empty; RestApiPluginConfig (packages/rest/src/rest-api-plugin.ts:95-105) is exactly {serverServiceName?, protocolServiceName?, kernelManagerServiceName?, api?}
5a heading in this file may be bound by check:skill-identifier-liveness Leg 2YES, and it is. Binding api-methods binds ## API Methods (Operations) to ApiMethod (scripts/check-skill-identifier-liveness.mjs:285-292). Fixed the author's way: the heading and all six primitives stay; only the derived rows moved. Gate green, 9 bindings, 0 ledgered gaps
6a false premise is skipped and listedapplied to the getService clause above

Token delta

filebeforeafterΔceiling
skills/objectstack-api/SKILL.md63114635−1,676 (−26.6%)6319, unchanged (headroom 8 → 1684)
skills/objectstack-api/evals/README.md5465460546 — untouched, API-H-01 deferred
skills/objectstack-api/references/_index.md8888880generator-owned, untouched
bundle, ratcheted (authored)171406169730−1,676171743

607 → 428 lines. No ceiling raised, no new file, no file deleted, and scripts/check-skills-token-ratchet.mjs is not edited.

The gap, itemised rather than smoothed. The dispatch target was −1,725 to −2,100; this lands at −1,676, short by 49 tokens (2.8%). It is not spread thin — it is two opposing errors in the audit's own estimates:

  • the three funded additions cost 239 tokens more than funded: F-01 271 actual vs +130 budgeted; F-02 162 vs +120; F-03 +96 net vs +40. Each was trimmed once already (F-01 from 407 tokens, F-02 from 250); trimming further would start dropping the load-bearing clauses each was funded to carry.
  • the deletions cut about 190 tokens more than the audit's per-span estimates, which is what absorbs most of that.

Closing the last 49 would mean cutting content no finding covers. Deliberately not done.

follow-up for objectstack-data / objectstack-platform

Both anchors are stronger than what this PR deleted, on every axis but one. Verified by heading on origin/claude/issue-14297-skills-data-optimization and origin/claude/issue-14299-skills-platform-optimization (what will merge):

  • objectstack-data/rules/datasources.md — byte-identical to origin/main on the data flight's branch; headings ## schemaMode — who owns the schema, ## Auto-connect (no onEnable), ## Credentials — fail-closed, ## Writes — double opt-in. ✅
  • objectstack-platform/SKILL.md## Driver Selection Guide — carries driver packages, class names, and the Turso "Cloud / EE onlyUnsupportedDriverError" caveat that the deleted api table omitted. ✅ Also ## Well-Known Plugin Names & Services and rules/service-registry.md both present. ✅
  • the one gap: neither anchor names the driver id vocabulary an author actually writes in defineDatasource({ driver: … })postgres, mysql, mongodb, sqlite, sqlite-wasm, turso, memory, and the mongo alias. The deleted api table did. Nothing is lost here — the pointer names the authoritative source, packages/spec/src/data/driver/config-registry.zod.ts:163 (resolveDriverId handles the aliases) — but a row in objectstack-data/rules/datasources.md would be the right home. Not filed as a card: it is one row inside a flight already in review; raising it here so that flight's reviewer can take it.

One file outside the declared surface, and why

scripts/role-word-baseline.jsoncheck:role-word went red on this branch with its ratchet-DOWN remedy, because API-C-03 deleted the file's single baselined occurrence of the reserved word (the Security Layers row | **RBAC** | Object | Role-based access control (profile → permissions) |). The gate names --update as the author's own path when a baselined file goes clean; leaving the entry would leave budget a later edit could spend silently. Baseline 43 → 42 files; the skills/objectstack-api/SKILL.md row is dropped, no other row moves. Committed separately.

Out-of-scope card filed

#14446 — declared ≠ enforced (ADR-0049): RealtimeEventType (packages/spec/src/api/realtime.zod.ts:33-40) spells record.* while the platform emits data.record.* (api/events.zod.ts:139-141), and SubscriptionSchema.filters is z.unknown().optional() (realtime.zod.ts:49). finding label, unassigned, no pm-state, no priority. Dedupe searched first — the four nearest cards (#4602, #4626, #4673, #9055) are all closed and none covers this pair.

Gates — head sha 19ee5853

Union re-derived after regeneration and again after the final commit: node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands42 commands (the .mdx output pulled in the docs family; the role-word baseline added 6 more: check:bash32-floor, check:cli-command-ids, check:entry-guard, check:parse-guard, check:pnpm-filter-targets, check:watch-hint-literal). All 42 run at 19ee5853; every exit code captured before any pipe.

41 green, 1 NOT MEASURED, 0 red.

  • node scripts/check-skills-token-ratchet.mjs✓ … 38 authored bundle file(s) within their ceilings
  • pnpm --filter @objectstack/spec check:skill-examples✅ 255 prose examples type-check across 3 surface(s) — every marked block parsed, so tsc ran the SEMANTIC pass on all of them (run under the shared verify lock; os-verify-lock: VERDICT command-exit 0). @objectstack/spec, @objectstack/client-react and @objectstack/formula closures built first, also under the lock — VERDICT command-exit 0 — so this gate could refuse rather than false-green.
  • pnpm check:skill-identifier-livenessOK — Leg 1: 488 citation(s) over 48 published file(s) …; Leg 2: 9 registered exhaustive section(s), 0 ledgered gap(s) (baseline was 500 citations; the drop is the deleted tables)
  • pnpm check:skill-compatibility✓ … 11 SKILL.md file(s) reconciled against 78 workspace packages
  • pnpm --filter @objectstack/spec check:skill-docs✅ Skill docs in sync
  • pnpm check:role-word after the ratchet-down
  • node scripts/check-nul-bytes.mjsOK (scanned 7875 text file(s) … no raw ASCII control bytes), plus a direct control-byte grep over the three edited files: no hits
  • NOT MEASURED:node scripts/check-test-completeness.mjs exits 3, its own "PREREQUISITE NOT MET" code — it needs a saved turbo run test log this run has no reason to produce. Its own text: "Nothing was measured … It is NOT a finding". CI supplies the log.

Two gates were exit-3 / exit-1 prerequisite states on the first pass and turned green once the closures were built, not by any edit: check:doc-formula-expressions + check:doc-security-posture (needed @objectstack/formula built) and check:docs (needed gen:schema, which build runs first).

Labels

skip-changeset — nothing released by any package changes. Checked against scripts/check-empty-changeset.mjs's own enumeration (:357: "It releases nothing (.github/, .claude/, skills/, docs/, content/, examples/…)"); this diff is skills/** + content/docs/** + one scripts/ ledger. needs:contract-review on both this PR and the card — the OCC contract, the error-ledger rule and the http.server mount timing are contract-semantics claims.

Stays draft: governed face.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1


Generated by Claude Code

…Schema example; teach http.server mount, the ADR-0112 code ledger and OCC
Optimization flight over skills/objectstack-api/SKILL.md (audit record posted
on the card). Shrink-only, additions paid by deletions in the same file.
DELETE / MERGE / REWRITE
API-E-01 the leading os:check example taught RestApiEndpointSchema: 0
consumers repo-wide, no plugin-rest-api package, and
RestApiPluginConfig has no `endpoints` key. The one live fact
(auth is the flat public + permissions pair) folded into the
auth section.
API-C-01 datasources + driver table -> objectstack-data rules/datasources.md
and objectstack-platform "Driver Selection Guide" (both carry more
than this file did, including the Turso Cloud/EE caveat).
API-C-02 inter-service communication -> objectstack-platform
rules/service-registry.md. Removes the `declare const kernel`
block that type-checked against a fabricated host shape.
API-C-03 Security Layers table named no authorable key -> one boundary line.
API-D-01 health/readiness response bodies -> one line (F-05, A-03).
API-D-02 Handler Status table, neutralised by its own callout.
API-D-03 Best Practices 1 and 4 (duplicate / no key, no gate).
API-D-04 Pitfalls 1, 2, 4 (FLS has no authorable spelling; the page sizes
match no platform constant; rate limiting is stated at D6).
API-D-05 the carve-out why-prose; the rule stays.
API-B-01 third rendering of "no nested auth block".
API-B-02 second gate invocation (and the `objectstack validate` spelling,
API-G-01) -> Verify your work states it once.
API-B-03 the apiMethods primitives/derived rule, stated 3x -> once. The
`## API Methods (Operations)` heading and all six ApiMethod members
stay: it is a registered exhaustive section (binding `api-methods`
in scripts/check-skill-identifier-liveness.mjs).
API-B-05 preamble restating the frontmatter.
API-F-04 environment-scoped routes / projectResolution, 0 usages (G-03).
API-F-05 ServiceInfo, a response shape with 0 usages -> one line.
API-F-06 the two declared-but-unenforced realtime notes (filed separately).
API-A-01 "When to Use This Skill" -> Skill Boundaries table, matching the
objectstack-data / objectstack-query form.
API-A-02 frontmatter drops the "versioning" promise: versioning.zod.ts has
zero consumers outside a pin test.
API-A-03 the description forbids the client seat; the body taught it.
ADD (funded)
API-F-01 the http.server code-mount example, the only code-route pattern the
repo ships. Left UNMARKED: `ctx` is @objectstack/core's
PluginContext and the skills os:check surface resolves
@objectstack/spec only, so a marker would need a locally declared
stand-in -- the same thing API-C-02 was deleted for.
Measured correction to the audit: ctx.getService is SYNCHRONOUS and
throws (0 awaited call sites in packages/plugins, 112 sync).
API-F-02 the ADR-0112 two-tier error-code ledger and the downstream
envelopeViolations + makeApiErrorSchema composition.
API-F-03 OCC stated with its real spellings: If-Match header or
expectedVersion body field, body wins, 409 CONCURRENT_UPDATE.
6311 -> 4635 tokens (ceiling 6319, unchanged); 607 -> 429 lines.
Part of #14304
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
…matter edit
Generator output only: `pnpm --filter @objectstack/spec gen:skill-docs` writes
both files from the SKILL.md frontmatter, and `check:skill-docs` fails without
this. The only change is API-A-02 dropping "versioning" from the description.
Part of #14304
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
`check:role-word` red on this branch with the ratchet-DOWN remedy: the file's
one baselined occurrence of the reserved word was the Security Layers row
`| **RBAC** | Object | Role-based access control (profile -> permissions) |`,
deleted by API-C-03. The gate names `--update` as the author's own path when a
baselined file goes clean, so the entry is dropped rather than left as budget a
later edit could spend silently. Baseline 43 -> 42 files; the objectstack-api
row is gone, no other row moves.
Part of #14304
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
@os-zhuang
os-zhuang marked this pull request as ready for review September 2, 2026 08:26
@os-zhuang
os-zhuang added this pull request to the merge queueSep 2, 2026
Merged via the queue into main with commit bae4088Sep 2, 2026
44 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-14304-skills-api-optimization branch September 2, 2026 09:03
os-zhuang added a commit that referenced this pull request Sep 2, 2026
…e base (#13823)
The published skill taught handlerStatus at this PR's base; main dropped that
teaching in the #14448 optimization flight (bae4088), so the changeset —
release-notes input — no longer claims an outstanding skills limb.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GDA48PuRFrHyRfdkBz8m21
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/mskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@os-litant@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

skills(api): optimization flight — RestApiEndpointSchema example and other packages' anchors cut, the apiMethods rule stated once, http.server mount / error ledger / OCC taught (net −1,676 tokens) - #14448

Merged
os-zhuang merged 3 commits into
mainfrom
claude/issue-14304-skills-api-optimization
Sep 2, 2026
Merged

Conversation

@os-litant

Copy link
Copy Markdown
Collaborator

Part of #14304

The audit record this implements is posted verbatim on the card. Every claim written into the file was re-verified at source on this branch's base; the file:line for each is below. evals/README.md is untouched (API-H-01 is deferred to #14296 item 2), so the card stays open — that is why the first line is Part of, not a closing keyword.

Per-item: 落点 | before | after

finding落点 (before)beforeafter
API-E-01SKILL.md:117-146 — the leading os:check exampleauthored RestApiEndpointSchema "via the REST API plugin"deleted. The one live fact (auth is the flat public + permissions pair, no name/request/response field) folded into Auth Configuration
API-C-01:472-510 Datasource Configuration + Supported Driversa defineDatasource example and a 7-row driver tabledeleted → one pointer: objectstack-data rules/datasources.md, objectstack-platform Driver Selection Guide, and data/driver/config-registry.zod.ts for the id vocabulary
API-C-02:513-538 Inter-Service CommunicationIDataEngine contract prose + a marked block whose declare const kernel fabricated the hostdeleted → the section's slot now carries the API-F-02 construct; service resolution points at objectstack-platform rules/service-registry.md
API-C-03:458-468 Security Layersa 4-row table naming no authorable key + a callout restating its own Description columndeleted → one boundary line under Authentication & Authorization
API-D-01 + API-F-05 + API-A-03:316-366 Service Discovery / Healtha ServiceInfoos:check example, a JSON health body, /ready proserewritten to 3 lines — all three are response surfaces, nothing to author
API-D-02:383-396 Handler Statusa 3-row table its own callout neutralised ("nothing reads it at runtime")deleted; the now-single-child ## Dispatcher & Routing wrapper collapses into ## Dispatcher Error Codes
API-B-01:419-429third rendering of "no nested auth block" + an unmarked duplicate fragmentdeleted, merged into one sentence that also carries the API-E-01 fold
API-B-02 + API-G-01:203-209a second objectstack validate gate block 384 lines from the firstdeleted — the gate is stated once, in Verify your work, in the bundle-dominant os spelling
API-B-03:65-71, :283-313, :559-563the apiMethods primitives/derived rule stated 3×once. Callout → 3 lines; derived table drops the 3 rows with no route and no derivation (history/restore/purge keep a one-line mention); Best Practice 6 stops restating it
API-B-05:22-28preamble restating the frontmatter above the folddeleted
API-A-01:31-39 "When to Use This Skill"6 bullets, 3 of which misrouteSkill Boundaries table, matching objectstack-data / objectstack-query
API-A-02frontmatter :3-12promises "batch/versioning contracts""batch contracts"versioning.zod.ts has zero consumers outside a pin test
API-A-03:83-94three /meta client query-param contracts2 lines saying they are client contracts nothing declares
API-D-03:544-547, :556-558Best Practices 1 and 4deleted (1 duplicates :273 and is wrong for the carve-out; 4 names no key and no gate)
API-D-04:569-576Pitfalls 1, 2, 4deleted — FLS has no authorable spelling in the bundle, the page sizes match no platform constant, rate limiting is already the D6 rule
API-D-05:191-198two why-paragraphs after the carve-out ruledeleted, rule kept
API-F-04 + API-G-03:275-279environment-scoped routes + projectResolution, 0 usagesdeleted (takes the retired project gloss with it)
API-F-06:404-411two declared-but-unenforced realtime notesdeleted from the skill; filed as #14446
API-G-02:481defineDatasource imported from the root barrelmoot — deleted with API-C-01
API-F-01(add)gap — :164 named http.server with no exampleone table cellnew ## Code routes: mounting on http.server` section
API-F-02(add)gap — :548-555frontmatter promised "error envelopes"; the ledger rule was absentnew ## Error Envelopes & the Code Ledger (ADR-0112)
API-F-03(add):575-576"use optimistic locking (version field)", naming no spellingthe two real spellings, body-wins, 409 CONCURRENT_UPDATE

The three funded additions — every claim, with its source

1. http.server code mount — verified against all three shipping sites (examples/app-showcase/src/system/server/recalc-endpoint.ts:48-118, packages/plugins/plugin-sharing/src/sharing-plugin.ts:787-790, packages/plugins/plugin-approvals/src/approvals-plugin.ts:353-356).

  • dual lookup readServer('http.server') ?? readServer('http-server'), canonical first — sharing-plugin.ts:787-790, approvals-plugin.ts:353-356; both carry the same comment that http.server is "the ONLY name present on all provider paths".
  • kernel:ready, not later — packages/spec/src/contracts/plugin-lifecycle-events.ts:70-91: listen() is deferred to kernel:listeningbecause "route registration in Hono … seals the matcher the first time a request is matched"; recalc-endpoint.ts:110-112 hooks kernel:ready.
  • the handler signature — RouteHandler = (req: IHttpRequest, res: IHttpResponse) at packages/spec/src/contracts/http-server.ts:108-111; IHttpResponse.status(code): IHttpResponse at :77 (so res.status(200).json(…) chains); IHttpServer.post at :216.
  • the block is NOT os:check-marked, deliberately. See "Assumption 3" below — this is measured, not assumed.

2. ADR-0112 error-code ledgerpackages/spec/src/api/error-code-ledger.zod.ts:6-56 states the two tiers, "An unregistered code fails schema parse — which fails the envelope conformance suites — which fails CI", the framework-packages-only scope rule (#4805, maintainer ruling 2026-08-03 re-confirmed 2026-08-09), and the downstream composition. Functions re-located by content on this base: makeApiErrorSchema at packages/spec/src/api/contract.zod.ts:146, envelopeViolations at :215.

3. OCCpackages/rest/src/rest-server.ts:7710-7727 is the PATCH /api/v1/data/:object/:id route: If-Match header or expectedVersion body field, const expectedVersion = bodyVersion ?? ifMatchHeader (body wins), and the field is stripped from the write payload. The token semantics, the 409 and the "" refusal are the spec's own .describe() at packages/spec/src/api/protocol.zod.ts:2097-2102. CONCURRENT_UPDATE is registered at packages/spec/src/api/error-code-ledger.zod.ts:168 and pinned to 409 at packages/rest/src/rest-unclassified-fault-status.test.ts:230.

premise_false

API-F-01, the "getService is async" clause — the audit's premise is false and was NOT written. The real host contract is PluginContext.getService[T](name: string): T (packages/core/src/types.ts:36, doc comment @throws Error if service not found) — synchronous, and it throws. Measured on this base:

  • await ctx.getService in packages/plugins/**, excluding tests: 0 occurrences.
  • non-awaited ctx.getService( / ctx.getService[T](, same scope: 112.
  • the three app sites are ctx?.getService?.('manifest') with no await (packages/apps/{account,setup,studio}/src/index.ts:{60,55,68}).

The audit's evidence for "async" was recalc-endpoint.ts:52, which awaits — but that file's ctx is its own locally declared RecalcHostContext (:30-35) whose getService?: (name) => Promise<T> is a shim, not the host. That is precisely the defect API-C-02 was deleted for, so the skill states the true rule instead: getService is synchronous and throws, which is exactly why each name needs its own try and a() ?? b() in one try never reaches b.

The :532 "fix or unmark" item needs neither — the block is deleted with API-C-02, so no marker survives to prove or disprove anything.

PM assumptions — all six measured

#assumptionverdict
1skills/objectstack-api/** byte-identical a59f78d ↔ baseHOLDSgit diff a59f78d 96b627d1 -- skills/objectstack-api/ is empty; every audited span matched by content
2the frontmatter edit forces regeneration of BOTH generated filesHOLDScheck:skill-docs red on both before gen:skill-docs, green after; the .mdx pulled 20 docs-family gates into the union, re-derived and run
3the real PluginContext is unreachable from the os:check skills surfaceHOLDS, measured directly.SURFACES[0] resolves resolutionDir/selfPackages = packages/spec only (packages/spec/scripts/check-skill-examples.ts:526-532). Probed it: a temporary marked block importing PluginContext from @objectstack/core fails TS2307: Cannot find module '@objectstack/core'. Probe reverted and proven byte-identical (worktree blob hash == HEAD blob hash, git diff HEAD empty). ⇒ the F-01 block stays unmarked rather than earning a marker with a fabricated stand-in
4RestApiEndpointSchema 0 consumers · no plugin-rest-api package · no endpoints keyHOLDS — 0 hits outside packages/spec/src/api/plugin-rest-api* (positive control: the same grep for ApiEndpoint returns many); ls packages/plugins/ | grep -i rest empty; RestApiPluginConfig (packages/rest/src/rest-api-plugin.ts:95-105) is exactly {serverServiceName?, protocolServiceName?, kernelManagerServiceName?, api?}
5a heading in this file may be bound by check:skill-identifier-liveness Leg 2YES, and it is. Binding api-methods binds ## API Methods (Operations) to ApiMethod (scripts/check-skill-identifier-liveness.mjs:285-292). Fixed the author's way: the heading and all six primitives stay; only the derived rows moved. Gate green, 9 bindings, 0 ledgered gaps
6a false premise is skipped and listedapplied to the getService clause above

Token delta

filebeforeafterΔceiling
skills/objectstack-api/SKILL.md63114635−1,676 (−26.6%)6319, unchanged (headroom 8 → 1684)
skills/objectstack-api/evals/README.md5465460546 — untouched, API-H-01 deferred
skills/objectstack-api/references/_index.md8888880generator-owned, untouched
bundle, ratcheted (authored)171406169730−1,676171743

607 → 428 lines. No ceiling raised, no new file, no file deleted, and scripts/check-skills-token-ratchet.mjs is not edited.

The gap, itemised rather than smoothed. The dispatch target was −1,725 to −2,100; this lands at −1,676, short by 49 tokens (2.8%). It is not spread thin — it is two opposing errors in the audit's own estimates:

  • the three funded additions cost 239 tokens more than funded: F-01 271 actual vs +130 budgeted; F-02 162 vs +120; F-03 +96 net vs +40. Each was trimmed once already (F-01 from 407 tokens, F-02 from 250); trimming further would start dropping the load-bearing clauses each was funded to carry.
  • the deletions cut about 190 tokens more than the audit's per-span estimates, which is what absorbs most of that.

Closing the last 49 would mean cutting content no finding covers. Deliberately not done.

follow-up for objectstack-data / objectstack-platform

Both anchors are stronger than what this PR deleted, on every axis but one. Verified by heading on origin/claude/issue-14297-skills-data-optimization and origin/claude/issue-14299-skills-platform-optimization (what will merge):

  • objectstack-data/rules/datasources.md — byte-identical to origin/main on the data flight's branch; headings ## schemaMode — who owns the schema, ## Auto-connect (no onEnable), ## Credentials — fail-closed, ## Writes — double opt-in. ✅
  • objectstack-platform/SKILL.md## Driver Selection Guide — carries driver packages, class names, and the Turso "Cloud / EE onlyUnsupportedDriverError" caveat that the deleted api table omitted. ✅ Also ## Well-Known Plugin Names & Services and rules/service-registry.md both present. ✅
  • the one gap: neither anchor names the driver id vocabulary an author actually writes in defineDatasource({ driver: … })postgres, mysql, mongodb, sqlite, sqlite-wasm, turso, memory, and the mongo alias. The deleted api table did. Nothing is lost here — the pointer names the authoritative source, packages/spec/src/data/driver/config-registry.zod.ts:163 (resolveDriverId handles the aliases) — but a row in objectstack-data/rules/datasources.md would be the right home. Not filed as a card: it is one row inside a flight already in review; raising it here so that flight's reviewer can take it.

One file outside the declared surface, and why

scripts/role-word-baseline.jsoncheck:role-word went red on this branch with its ratchet-DOWN remedy, because API-C-03 deleted the file's single baselined occurrence of the reserved word (the Security Layers row | **RBAC** | Object | Role-based access control (profile → permissions) |). The gate names --update as the author's own path when a baselined file goes clean; leaving the entry would leave budget a later edit could spend silently. Baseline 43 → 42 files; the skills/objectstack-api/SKILL.md row is dropped, no other row moves. Committed separately.

Out-of-scope card filed

#14446 — declared ≠ enforced (ADR-0049): RealtimeEventType (packages/spec/src/api/realtime.zod.ts:33-40) spells record.* while the platform emits data.record.* (api/events.zod.ts:139-141), and SubscriptionSchema.filters is z.unknown().optional() (realtime.zod.ts:49). finding label, unassigned, no pm-state, no priority. Dedupe searched first — the four nearest cards (#4602, #4626, #4673, #9055) are all closed and none covers this pair.

Gates — head sha 19ee5853

Union re-derived after regeneration and again after the final commit: node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands42 commands (the .mdx output pulled in the docs family; the role-word baseline added 6 more: check:bash32-floor, check:cli-command-ids, check:entry-guard, check:parse-guard, check:pnpm-filter-targets, check:watch-hint-literal). All 42 run at 19ee5853; every exit code captured before any pipe.

41 green, 1 NOT MEASURED, 0 red.

  • node scripts/check-skills-token-ratchet.mjs✓ … 38 authored bundle file(s) within their ceilings
  • pnpm --filter @objectstack/spec check:skill-examples✅ 255 prose examples type-check across 3 surface(s) — every marked block parsed, so tsc ran the SEMANTIC pass on all of them (run under the shared verify lock; os-verify-lock: VERDICT command-exit 0). @objectstack/spec, @objectstack/client-react and @objectstack/formula closures built first, also under the lock — VERDICT command-exit 0 — so this gate could refuse rather than false-green.
  • pnpm check:skill-identifier-livenessOK — Leg 1: 488 citation(s) over 48 published file(s) …; Leg 2: 9 registered exhaustive section(s), 0 ledgered gap(s) (baseline was 500 citations; the drop is the deleted tables)
  • pnpm check:skill-compatibility✓ … 11 SKILL.md file(s) reconciled against 78 workspace packages
  • pnpm --filter @objectstack/spec check:skill-docs✅ Skill docs in sync
  • pnpm check:role-word after the ratchet-down
  • node scripts/check-nul-bytes.mjsOK (scanned 7875 text file(s) … no raw ASCII control bytes), plus a direct control-byte grep over the three edited files: no hits
  • NOT MEASURED:node scripts/check-test-completeness.mjs exits 3, its own "PREREQUISITE NOT MET" code — it needs a saved turbo run test log this run has no reason to produce. Its own text: "Nothing was measured … It is NOT a finding". CI supplies the log.

Two gates were exit-3 / exit-1 prerequisite states on the first pass and turned green once the closures were built, not by any edit: check:doc-formula-expressions + check:doc-security-posture (needed @objectstack/formula built) and check:docs (needed gen:schema, which build runs first).

Labels

skip-changeset — nothing released by any package changes. Checked against scripts/check-empty-changeset.mjs's own enumeration (:357: "It releases nothing (.github/, .claude/, skills/, docs/, content/, examples/…)"); this diff is skills/** + content/docs/** + one scripts/ ledger. needs:contract-review on both this PR and the card — the OCC contract, the error-ledger rule and the http.server mount timing are contract-semantics claims.

Stays draft: governed face.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1


Generated by Claude Code

…Schema example; teach http.server mount, the ADR-0112 code ledger and OCC
Optimization flight over skills/objectstack-api/SKILL.md (audit record posted
on the card). Shrink-only, additions paid by deletions in the same file.
DELETE / MERGE / REWRITE
API-E-01 the leading os:check example taught RestApiEndpointSchema: 0
consumers repo-wide, no plugin-rest-api package, and
RestApiPluginConfig has no `endpoints` key. The one live fact
(auth is the flat public + permissions pair) folded into the
auth section.
API-C-01 datasources + driver table -> objectstack-data rules/datasources.md
and objectstack-platform "Driver Selection Guide" (both carry more
than this file did, including the Turso Cloud/EE caveat).
API-C-02 inter-service communication -> objectstack-platform
rules/service-registry.md. Removes the `declare const kernel`
block that type-checked against a fabricated host shape.
API-C-03 Security Layers table named no authorable key -> one boundary line.
API-D-01 health/readiness response bodies -> one line (F-05, A-03).
API-D-02 Handler Status table, neutralised by its own callout.
API-D-03 Best Practices 1 and 4 (duplicate / no key, no gate).
API-D-04 Pitfalls 1, 2, 4 (FLS has no authorable spelling; the page sizes
match no platform constant; rate limiting is stated at D6).
API-D-05 the carve-out why-prose; the rule stays.
API-B-01 third rendering of "no nested auth block".
API-B-02 second gate invocation (and the `objectstack validate` spelling,
API-G-01) -> Verify your work states it once.
API-B-03 the apiMethods primitives/derived rule, stated 3x -> once. The
`## API Methods (Operations)` heading and all six ApiMethod members
stay: it is a registered exhaustive section (binding `api-methods`
in scripts/check-skill-identifier-liveness.mjs).
API-B-05 preamble restating the frontmatter.
API-F-04 environment-scoped routes / projectResolution, 0 usages (G-03).
API-F-05 ServiceInfo, a response shape with 0 usages -> one line.
API-F-06 the two declared-but-unenforced realtime notes (filed separately).
API-A-01 "When to Use This Skill" -> Skill Boundaries table, matching the
objectstack-data / objectstack-query form.
API-A-02 frontmatter drops the "versioning" promise: versioning.zod.ts has
zero consumers outside a pin test.
API-A-03 the description forbids the client seat; the body taught it.
ADD (funded)
API-F-01 the http.server code-mount example, the only code-route pattern the
repo ships. Left UNMARKED: `ctx` is @objectstack/core's
PluginContext and the skills os:check surface resolves
@objectstack/spec only, so a marker would need a locally declared
stand-in -- the same thing API-C-02 was deleted for.
Measured correction to the audit: ctx.getService is SYNCHRONOUS and
throws (0 awaited call sites in packages/plugins, 112 sync).
API-F-02 the ADR-0112 two-tier error-code ledger and the downstream
envelopeViolations + makeApiErrorSchema composition.
API-F-03 OCC stated with its real spellings: If-Match header or
expectedVersion body field, body wins, 409 CONCURRENT_UPDATE.
6311 -> 4635 tokens (ceiling 6319, unchanged); 607 -> 429 lines.
Part of #14304
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
…matter edit
Generator output only: `pnpm --filter @objectstack/spec gen:skill-docs` writes
both files from the SKILL.md frontmatter, and `check:skill-docs` fails without
this. The only change is API-A-02 dropping "versioning" from the description.
Part of #14304
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
`check:role-word` red on this branch with the ratchet-DOWN remedy: the file's
one baselined occurrence of the reserved word was the Security Layers row
`| **RBAC** | Object | Role-based access control (profile -> permissions) |`,
deleted by API-C-03. The gate names `--update` as the author's own path when a
baselined file goes clean, so the entry is dropped rather than left as budget a
later edit could spend silently. Baseline 43 -> 42 files; the objectstack-api
row is gone, no other row moves.
Part of #14304
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
@os-zhuang
os-zhuang marked this pull request as ready for review September 2, 2026 08:26
@os-zhuang
os-zhuang added this pull request to the merge queueSep 2, 2026
Merged via the queue into main with commit bae4088Sep 2, 2026
44 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-14304-skills-api-optimization branch September 2, 2026 09:03
os-zhuang added a commit that referenced this pull request Sep 2, 2026
…e base (#13823)
The published skill taught handlerStatus at this PR's base; main dropped that
teaching in the #14448 optimization flight (bae4088), so the changeset —
release-notes input — no longer claims an outstanding skills limb.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GDA48PuRFrHyRfdkBz8m21
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/mskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@os-litant@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

skills(api): optimization flight — RestApiEndpointSchema example and other packages' anchors cut, the apiMethods rule stated once, http.server mount / error ledger / OCC taught (net −1,676 tokens) - #14448

Merged
os-zhuang merged 3 commits into
mainfrom
claude/issue-14304-skills-api-optimization
Sep 2, 2026
Merged

Conversation

@os-litant

Copy link
Copy Markdown
Collaborator

Part of #14304

The audit record this implements is posted verbatim on the card. Every claim written into the file was re-verified at source on this branch's base; the file:line for each is below. evals/README.md is untouched (API-H-01 is deferred to #14296 item 2), so the card stays open — that is why the first line is Part of, not a closing keyword.

Per-item: 落点 | before | after

finding落点 (before)beforeafter
API-E-01SKILL.md:117-146 — the leading os:check exampleauthored RestApiEndpointSchema "via the REST API plugin"deleted. The one live fact (auth is the flat public + permissions pair, no name/request/response field) folded into Auth Configuration
API-C-01:472-510 Datasource Configuration + Supported Driversa defineDatasource example and a 7-row driver tabledeleted → one pointer: objectstack-data rules/datasources.md, objectstack-platform Driver Selection Guide, and data/driver/config-registry.zod.ts for the id vocabulary
API-C-02:513-538 Inter-Service CommunicationIDataEngine contract prose + a marked block whose declare const kernel fabricated the hostdeleted → the section's slot now carries the API-F-02 construct; service resolution points at objectstack-platform rules/service-registry.md
API-C-03:458-468 Security Layersa 4-row table naming no authorable key + a callout restating its own Description columndeleted → one boundary line under Authentication & Authorization
API-D-01 + API-F-05 + API-A-03:316-366 Service Discovery / Healtha ServiceInfoos:check example, a JSON health body, /ready proserewritten to 3 lines — all three are response surfaces, nothing to author
API-D-02:383-396 Handler Statusa 3-row table its own callout neutralised ("nothing reads it at runtime")deleted; the now-single-child ## Dispatcher & Routing wrapper collapses into ## Dispatcher Error Codes
API-B-01:419-429third rendering of "no nested auth block" + an unmarked duplicate fragmentdeleted, merged into one sentence that also carries the API-E-01 fold
API-B-02 + API-G-01:203-209a second objectstack validate gate block 384 lines from the firstdeleted — the gate is stated once, in Verify your work, in the bundle-dominant os spelling
API-B-03:65-71, :283-313, :559-563the apiMethods primitives/derived rule stated 3×once. Callout → 3 lines; derived table drops the 3 rows with no route and no derivation (history/restore/purge keep a one-line mention); Best Practice 6 stops restating it
API-B-05:22-28preamble restating the frontmatter above the folddeleted
API-A-01:31-39 "When to Use This Skill"6 bullets, 3 of which misrouteSkill Boundaries table, matching objectstack-data / objectstack-query
API-A-02frontmatter :3-12promises "batch/versioning contracts""batch contracts"versioning.zod.ts has zero consumers outside a pin test
API-A-03:83-94three /meta client query-param contracts2 lines saying they are client contracts nothing declares
API-D-03:544-547, :556-558Best Practices 1 and 4deleted (1 duplicates :273 and is wrong for the carve-out; 4 names no key and no gate)
API-D-04:569-576Pitfalls 1, 2, 4deleted — FLS has no authorable spelling in the bundle, the page sizes match no platform constant, rate limiting is already the D6 rule
API-D-05:191-198two why-paragraphs after the carve-out ruledeleted, rule kept
API-F-04 + API-G-03:275-279environment-scoped routes + projectResolution, 0 usagesdeleted (takes the retired project gloss with it)
API-F-06:404-411two declared-but-unenforced realtime notesdeleted from the skill; filed as #14446
API-G-02:481defineDatasource imported from the root barrelmoot — deleted with API-C-01
API-F-01(add)gap — :164 named http.server with no exampleone table cellnew ## Code routes: mounting on http.server` section
API-F-02(add)gap — :548-555frontmatter promised "error envelopes"; the ledger rule was absentnew ## Error Envelopes & the Code Ledger (ADR-0112)
API-F-03(add):575-576"use optimistic locking (version field)", naming no spellingthe two real spellings, body-wins, 409 CONCURRENT_UPDATE

The three funded additions — every claim, with its source

1. http.server code mount — verified against all three shipping sites (examples/app-showcase/src/system/server/recalc-endpoint.ts:48-118, packages/plugins/plugin-sharing/src/sharing-plugin.ts:787-790, packages/plugins/plugin-approvals/src/approvals-plugin.ts:353-356).

  • dual lookup readServer('http.server') ?? readServer('http-server'), canonical first — sharing-plugin.ts:787-790, approvals-plugin.ts:353-356; both carry the same comment that http.server is "the ONLY name present on all provider paths".
  • kernel:ready, not later — packages/spec/src/contracts/plugin-lifecycle-events.ts:70-91: listen() is deferred to kernel:listeningbecause "route registration in Hono … seals the matcher the first time a request is matched"; recalc-endpoint.ts:110-112 hooks kernel:ready.
  • the handler signature — RouteHandler = (req: IHttpRequest, res: IHttpResponse) at packages/spec/src/contracts/http-server.ts:108-111; IHttpResponse.status(code): IHttpResponse at :77 (so res.status(200).json(…) chains); IHttpServer.post at :216.
  • the block is NOT os:check-marked, deliberately. See "Assumption 3" below — this is measured, not assumed.

2. ADR-0112 error-code ledgerpackages/spec/src/api/error-code-ledger.zod.ts:6-56 states the two tiers, "An unregistered code fails schema parse — which fails the envelope conformance suites — which fails CI", the framework-packages-only scope rule (#4805, maintainer ruling 2026-08-03 re-confirmed 2026-08-09), and the downstream composition. Functions re-located by content on this base: makeApiErrorSchema at packages/spec/src/api/contract.zod.ts:146, envelopeViolations at :215.

3. OCCpackages/rest/src/rest-server.ts:7710-7727 is the PATCH /api/v1/data/:object/:id route: If-Match header or expectedVersion body field, const expectedVersion = bodyVersion ?? ifMatchHeader (body wins), and the field is stripped from the write payload. The token semantics, the 409 and the "" refusal are the spec's own .describe() at packages/spec/src/api/protocol.zod.ts:2097-2102. CONCURRENT_UPDATE is registered at packages/spec/src/api/error-code-ledger.zod.ts:168 and pinned to 409 at packages/rest/src/rest-unclassified-fault-status.test.ts:230.

premise_false

API-F-01, the "getService is async" clause — the audit's premise is false and was NOT written. The real host contract is PluginContext.getService[T](name: string): T (packages/core/src/types.ts:36, doc comment @throws Error if service not found) — synchronous, and it throws. Measured on this base:

  • await ctx.getService in packages/plugins/**, excluding tests: 0 occurrences.
  • non-awaited ctx.getService( / ctx.getService[T](, same scope: 112.
  • the three app sites are ctx?.getService?.('manifest') with no await (packages/apps/{account,setup,studio}/src/index.ts:{60,55,68}).

The audit's evidence for "async" was recalc-endpoint.ts:52, which awaits — but that file's ctx is its own locally declared RecalcHostContext (:30-35) whose getService?: (name) => Promise<T> is a shim, not the host. That is precisely the defect API-C-02 was deleted for, so the skill states the true rule instead: getService is synchronous and throws, which is exactly why each name needs its own try and a() ?? b() in one try never reaches b.

The :532 "fix or unmark" item needs neither — the block is deleted with API-C-02, so no marker survives to prove or disprove anything.

PM assumptions — all six measured

#assumptionverdict
1skills/objectstack-api/** byte-identical a59f78d ↔ baseHOLDSgit diff a59f78d 96b627d1 -- skills/objectstack-api/ is empty; every audited span matched by content
2the frontmatter edit forces regeneration of BOTH generated filesHOLDScheck:skill-docs red on both before gen:skill-docs, green after; the .mdx pulled 20 docs-family gates into the union, re-derived and run
3the real PluginContext is unreachable from the os:check skills surfaceHOLDS, measured directly.SURFACES[0] resolves resolutionDir/selfPackages = packages/spec only (packages/spec/scripts/check-skill-examples.ts:526-532). Probed it: a temporary marked block importing PluginContext from @objectstack/core fails TS2307: Cannot find module '@objectstack/core'. Probe reverted and proven byte-identical (worktree blob hash == HEAD blob hash, git diff HEAD empty). ⇒ the F-01 block stays unmarked rather than earning a marker with a fabricated stand-in
4RestApiEndpointSchema 0 consumers · no plugin-rest-api package · no endpoints keyHOLDS — 0 hits outside packages/spec/src/api/plugin-rest-api* (positive control: the same grep for ApiEndpoint returns many); ls packages/plugins/ | grep -i rest empty; RestApiPluginConfig (packages/rest/src/rest-api-plugin.ts:95-105) is exactly {serverServiceName?, protocolServiceName?, kernelManagerServiceName?, api?}
5a heading in this file may be bound by check:skill-identifier-liveness Leg 2YES, and it is. Binding api-methods binds ## API Methods (Operations) to ApiMethod (scripts/check-skill-identifier-liveness.mjs:285-292). Fixed the author's way: the heading and all six primitives stay; only the derived rows moved. Gate green, 9 bindings, 0 ledgered gaps
6a false premise is skipped and listedapplied to the getService clause above

Token delta

filebeforeafterΔceiling
skills/objectstack-api/SKILL.md63114635−1,676 (−26.6%)6319, unchanged (headroom 8 → 1684)
skills/objectstack-api/evals/README.md5465460546 — untouched, API-H-01 deferred
skills/objectstack-api/references/_index.md8888880generator-owned, untouched
bundle, ratcheted (authored)171406169730−1,676171743

607 → 428 lines. No ceiling raised, no new file, no file deleted, and scripts/check-skills-token-ratchet.mjs is not edited.

The gap, itemised rather than smoothed. The dispatch target was −1,725 to −2,100; this lands at −1,676, short by 49 tokens (2.8%). It is not spread thin — it is two opposing errors in the audit's own estimates:

  • the three funded additions cost 239 tokens more than funded: F-01 271 actual vs +130 budgeted; F-02 162 vs +120; F-03 +96 net vs +40. Each was trimmed once already (F-01 from 407 tokens, F-02 from 250); trimming further would start dropping the load-bearing clauses each was funded to carry.
  • the deletions cut about 190 tokens more than the audit's per-span estimates, which is what absorbs most of that.

Closing the last 49 would mean cutting content no finding covers. Deliberately not done.

follow-up for objectstack-data / objectstack-platform

Both anchors are stronger than what this PR deleted, on every axis but one. Verified by heading on origin/claude/issue-14297-skills-data-optimization and origin/claude/issue-14299-skills-platform-optimization (what will merge):

  • objectstack-data/rules/datasources.md — byte-identical to origin/main on the data flight's branch; headings ## schemaMode — who owns the schema, ## Auto-connect (no onEnable), ## Credentials — fail-closed, ## Writes — double opt-in. ✅
  • objectstack-platform/SKILL.md## Driver Selection Guide — carries driver packages, class names, and the Turso "Cloud / EE onlyUnsupportedDriverError" caveat that the deleted api table omitted. ✅ Also ## Well-Known Plugin Names & Services and rules/service-registry.md both present. ✅
  • the one gap: neither anchor names the driver id vocabulary an author actually writes in defineDatasource({ driver: … })postgres, mysql, mongodb, sqlite, sqlite-wasm, turso, memory, and the mongo alias. The deleted api table did. Nothing is lost here — the pointer names the authoritative source, packages/spec/src/data/driver/config-registry.zod.ts:163 (resolveDriverId handles the aliases) — but a row in objectstack-data/rules/datasources.md would be the right home. Not filed as a card: it is one row inside a flight already in review; raising it here so that flight's reviewer can take it.

One file outside the declared surface, and why

scripts/role-word-baseline.jsoncheck:role-word went red on this branch with its ratchet-DOWN remedy, because API-C-03 deleted the file's single baselined occurrence of the reserved word (the Security Layers row | **RBAC** | Object | Role-based access control (profile → permissions) |). The gate names --update as the author's own path when a baselined file goes clean; leaving the entry would leave budget a later edit could spend silently. Baseline 43 → 42 files; the skills/objectstack-api/SKILL.md row is dropped, no other row moves. Committed separately.

Out-of-scope card filed

#14446 — declared ≠ enforced (ADR-0049): RealtimeEventType (packages/spec/src/api/realtime.zod.ts:33-40) spells record.* while the platform emits data.record.* (api/events.zod.ts:139-141), and SubscriptionSchema.filters is z.unknown().optional() (realtime.zod.ts:49). finding label, unassigned, no pm-state, no priority. Dedupe searched first — the four nearest cards (#4602, #4626, #4673, #9055) are all closed and none covers this pair.

Gates — head sha 19ee5853

Union re-derived after regeneration and again after the final commit: node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands42 commands (the .mdx output pulled in the docs family; the role-word baseline added 6 more: check:bash32-floor, check:cli-command-ids, check:entry-guard, check:parse-guard, check:pnpm-filter-targets, check:watch-hint-literal). All 42 run at 19ee5853; every exit code captured before any pipe.

41 green, 1 NOT MEASURED, 0 red.

  • node scripts/check-skills-token-ratchet.mjs✓ … 38 authored bundle file(s) within their ceilings
  • pnpm --filter @objectstack/spec check:skill-examples✅ 255 prose examples type-check across 3 surface(s) — every marked block parsed, so tsc ran the SEMANTIC pass on all of them (run under the shared verify lock; os-verify-lock: VERDICT command-exit 0). @objectstack/spec, @objectstack/client-react and @objectstack/formula closures built first, also under the lock — VERDICT command-exit 0 — so this gate could refuse rather than false-green.
  • pnpm check:skill-identifier-livenessOK — Leg 1: 488 citation(s) over 48 published file(s) …; Leg 2: 9 registered exhaustive section(s), 0 ledgered gap(s) (baseline was 500 citations; the drop is the deleted tables)
  • pnpm check:skill-compatibility✓ … 11 SKILL.md file(s) reconciled against 78 workspace packages
  • pnpm --filter @objectstack/spec check:skill-docs✅ Skill docs in sync
  • pnpm check:role-word after the ratchet-down
  • node scripts/check-nul-bytes.mjsOK (scanned 7875 text file(s) … no raw ASCII control bytes), plus a direct control-byte grep over the three edited files: no hits
  • NOT MEASURED:node scripts/check-test-completeness.mjs exits 3, its own "PREREQUISITE NOT MET" code — it needs a saved turbo run test log this run has no reason to produce. Its own text: "Nothing was measured … It is NOT a finding". CI supplies the log.

Two gates were exit-3 / exit-1 prerequisite states on the first pass and turned green once the closures were built, not by any edit: check:doc-formula-expressions + check:doc-security-posture (needed @objectstack/formula built) and check:docs (needed gen:schema, which build runs first).

Labels

skip-changeset — nothing released by any package changes. Checked against scripts/check-empty-changeset.mjs's own enumeration (:357: "It releases nothing (.github/, .claude/, skills/, docs/, content/, examples/…)"); this diff is skills/** + content/docs/** + one scripts/ ledger. needs:contract-review on both this PR and the card — the OCC contract, the error-ledger rule and the http.server mount timing are contract-semantics claims.

Stays draft: governed face.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1


Generated by Claude Code

…Schema example; teach http.server mount, the ADR-0112 code ledger and OCC
Optimization flight over skills/objectstack-api/SKILL.md (audit record posted
on the card). Shrink-only, additions paid by deletions in the same file.
DELETE / MERGE / REWRITE
API-E-01 the leading os:check example taught RestApiEndpointSchema: 0
consumers repo-wide, no plugin-rest-api package, and
RestApiPluginConfig has no `endpoints` key. The one live fact
(auth is the flat public + permissions pair) folded into the
auth section.
API-C-01 datasources + driver table -> objectstack-data rules/datasources.md
and objectstack-platform "Driver Selection Guide" (both carry more
than this file did, including the Turso Cloud/EE caveat).
API-C-02 inter-service communication -> objectstack-platform
rules/service-registry.md. Removes the `declare const kernel`
block that type-checked against a fabricated host shape.
API-C-03 Security Layers table named no authorable key -> one boundary line.
API-D-01 health/readiness response bodies -> one line (F-05, A-03).
API-D-02 Handler Status table, neutralised by its own callout.
API-D-03 Best Practices 1 and 4 (duplicate / no key, no gate).
API-D-04 Pitfalls 1, 2, 4 (FLS has no authorable spelling; the page sizes
match no platform constant; rate limiting is stated at D6).
API-D-05 the carve-out why-prose; the rule stays.
API-B-01 third rendering of "no nested auth block".
API-B-02 second gate invocation (and the `objectstack validate` spelling,
API-G-01) -> Verify your work states it once.
API-B-03 the apiMethods primitives/derived rule, stated 3x -> once. The
`## API Methods (Operations)` heading and all six ApiMethod members
stay: it is a registered exhaustive section (binding `api-methods`
in scripts/check-skill-identifier-liveness.mjs).
API-B-05 preamble restating the frontmatter.
API-F-04 environment-scoped routes / projectResolution, 0 usages (G-03).
API-F-05 ServiceInfo, a response shape with 0 usages -> one line.
API-F-06 the two declared-but-unenforced realtime notes (filed separately).
API-A-01 "When to Use This Skill" -> Skill Boundaries table, matching the
objectstack-data / objectstack-query form.
API-A-02 frontmatter drops the "versioning" promise: versioning.zod.ts has
zero consumers outside a pin test.
API-A-03 the description forbids the client seat; the body taught it.
ADD (funded)
API-F-01 the http.server code-mount example, the only code-route pattern the
repo ships. Left UNMARKED: `ctx` is @objectstack/core's
PluginContext and the skills os:check surface resolves
@objectstack/spec only, so a marker would need a locally declared
stand-in -- the same thing API-C-02 was deleted for.
Measured correction to the audit: ctx.getService is SYNCHRONOUS and
throws (0 awaited call sites in packages/plugins, 112 sync).
API-F-02 the ADR-0112 two-tier error-code ledger and the downstream
envelopeViolations + makeApiErrorSchema composition.
API-F-03 OCC stated with its real spellings: If-Match header or
expectedVersion body field, body wins, 409 CONCURRENT_UPDATE.
6311 -> 4635 tokens (ceiling 6319, unchanged); 607 -> 429 lines.
Part of #14304
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
…matter edit
Generator output only: `pnpm --filter @objectstack/spec gen:skill-docs` writes
both files from the SKILL.md frontmatter, and `check:skill-docs` fails without
this. The only change is API-A-02 dropping "versioning" from the description.
Part of #14304
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
`check:role-word` red on this branch with the ratchet-DOWN remedy: the file's
one baselined occurrence of the reserved word was the Security Layers row
`| **RBAC** | Object | Role-based access control (profile -> permissions) |`,
deleted by API-C-03. The gate names `--update` as the author's own path when a
baselined file goes clean, so the entry is dropped rather than left as budget a
later edit could spend silently. Baseline 43 -> 42 files; the objectstack-api
row is gone, no other row moves.
Part of #14304
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
@os-zhuang
os-zhuang marked this pull request as ready for review September 2, 2026 08:26
@os-zhuang
os-zhuang added this pull request to the merge queueSep 2, 2026
Merged via the queue into main with commit bae4088Sep 2, 2026
44 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-14304-skills-api-optimization branch September 2, 2026 09:03
os-zhuang added a commit that referenced this pull request Sep 2, 2026
…e base (#13823)
The published skill taught handlerStatus at this PR's base; main dropped that
teaching in the #14448 optimization flight (bae4088), so the changeset —
release-notes input — no longer claims an outstanding skills limb.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GDA48PuRFrHyRfdkBz8m21
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/mskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@os-litant@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

skills(api): optimization flight — RestApiEndpointSchema example and other packages' anchors cut, the apiMethods rule stated once, http.server mount / error ledger / OCC taught (net −1,676 tokens) - #14448

Merged
os-zhuang merged 3 commits into
mainfrom
claude/issue-14304-skills-api-optimization
Sep 2, 2026
Merged

Conversation

@os-litant

Copy link
Copy Markdown
Collaborator

Part of #14304

The audit record this implements is posted verbatim on the card. Every claim written into the file was re-verified at source on this branch's base; the file:line for each is below. evals/README.md is untouched (API-H-01 is deferred to #14296 item 2), so the card stays open — that is why the first line is Part of, not a closing keyword.

Per-item: 落点 | before | after

finding落点 (before)beforeafter
API-E-01SKILL.md:117-146 — the leading os:check exampleauthored RestApiEndpointSchema "via the REST API plugin"deleted. The one live fact (auth is the flat public + permissions pair, no name/request/response field) folded into Auth Configuration
API-C-01:472-510 Datasource Configuration + Supported Driversa defineDatasource example and a 7-row driver tabledeleted → one pointer: objectstack-data rules/datasources.md, objectstack-platform Driver Selection Guide, and data/driver/config-registry.zod.ts for the id vocabulary
API-C-02:513-538 Inter-Service CommunicationIDataEngine contract prose + a marked block whose declare const kernel fabricated the hostdeleted → the section's slot now carries the API-F-02 construct; service resolution points at objectstack-platform rules/service-registry.md
API-C-03:458-468 Security Layersa 4-row table naming no authorable key + a callout restating its own Description columndeleted → one boundary line under Authentication & Authorization
API-D-01 + API-F-05 + API-A-03:316-366 Service Discovery / Healtha ServiceInfoos:check example, a JSON health body, /ready proserewritten to 3 lines — all three are response surfaces, nothing to author
API-D-02:383-396 Handler Statusa 3-row table its own callout neutralised ("nothing reads it at runtime")deleted; the now-single-child ## Dispatcher & Routing wrapper collapses into ## Dispatcher Error Codes
API-B-01:419-429third rendering of "no nested auth block" + an unmarked duplicate fragmentdeleted, merged into one sentence that also carries the API-E-01 fold
API-B-02 + API-G-01:203-209a second objectstack validate gate block 384 lines from the firstdeleted — the gate is stated once, in Verify your work, in the bundle-dominant os spelling
API-B-03:65-71, :283-313, :559-563the apiMethods primitives/derived rule stated 3×once. Callout → 3 lines; derived table drops the 3 rows with no route and no derivation (history/restore/purge keep a one-line mention); Best Practice 6 stops restating it
API-B-05:22-28preamble restating the frontmatter above the folddeleted
API-A-01:31-39 "When to Use This Skill"6 bullets, 3 of which misrouteSkill Boundaries table, matching objectstack-data / objectstack-query
API-A-02frontmatter :3-12promises "batch/versioning contracts""batch contracts"versioning.zod.ts has zero consumers outside a pin test
API-A-03:83-94three /meta client query-param contracts2 lines saying they are client contracts nothing declares
API-D-03:544-547, :556-558Best Practices 1 and 4deleted (1 duplicates :273 and is wrong for the carve-out; 4 names no key and no gate)
API-D-04:569-576Pitfalls 1, 2, 4deleted — FLS has no authorable spelling in the bundle, the page sizes match no platform constant, rate limiting is already the D6 rule
API-D-05:191-198two why-paragraphs after the carve-out ruledeleted, rule kept
API-F-04 + API-G-03:275-279environment-scoped routes + projectResolution, 0 usagesdeleted (takes the retired project gloss with it)
API-F-06:404-411two declared-but-unenforced realtime notesdeleted from the skill; filed as #14446
API-G-02:481defineDatasource imported from the root barrelmoot — deleted with API-C-01
API-F-01(add)gap — :164 named http.server with no exampleone table cellnew ## Code routes: mounting on http.server` section
API-F-02(add)gap — :548-555frontmatter promised "error envelopes"; the ledger rule was absentnew ## Error Envelopes & the Code Ledger (ADR-0112)
API-F-03(add):575-576"use optimistic locking (version field)", naming no spellingthe two real spellings, body-wins, 409 CONCURRENT_UPDATE

The three funded additions — every claim, with its source

1. http.server code mount — verified against all three shipping sites (examples/app-showcase/src/system/server/recalc-endpoint.ts:48-118, packages/plugins/plugin-sharing/src/sharing-plugin.ts:787-790, packages/plugins/plugin-approvals/src/approvals-plugin.ts:353-356).

  • dual lookup readServer('http.server') ?? readServer('http-server'), canonical first — sharing-plugin.ts:787-790, approvals-plugin.ts:353-356; both carry the same comment that http.server is "the ONLY name present on all provider paths".
  • kernel:ready, not later — packages/spec/src/contracts/plugin-lifecycle-events.ts:70-91: listen() is deferred to kernel:listeningbecause "route registration in Hono … seals the matcher the first time a request is matched"; recalc-endpoint.ts:110-112 hooks kernel:ready.
  • the handler signature — RouteHandler = (req: IHttpRequest, res: IHttpResponse) at packages/spec/src/contracts/http-server.ts:108-111; IHttpResponse.status(code): IHttpResponse at :77 (so res.status(200).json(…) chains); IHttpServer.post at :216.
  • the block is NOT os:check-marked, deliberately. See "Assumption 3" below — this is measured, not assumed.

2. ADR-0112 error-code ledgerpackages/spec/src/api/error-code-ledger.zod.ts:6-56 states the two tiers, "An unregistered code fails schema parse — which fails the envelope conformance suites — which fails CI", the framework-packages-only scope rule (#4805, maintainer ruling 2026-08-03 re-confirmed 2026-08-09), and the downstream composition. Functions re-located by content on this base: makeApiErrorSchema at packages/spec/src/api/contract.zod.ts:146, envelopeViolations at :215.

3. OCCpackages/rest/src/rest-server.ts:7710-7727 is the PATCH /api/v1/data/:object/:id route: If-Match header or expectedVersion body field, const expectedVersion = bodyVersion ?? ifMatchHeader (body wins), and the field is stripped from the write payload. The token semantics, the 409 and the "" refusal are the spec's own .describe() at packages/spec/src/api/protocol.zod.ts:2097-2102. CONCURRENT_UPDATE is registered at packages/spec/src/api/error-code-ledger.zod.ts:168 and pinned to 409 at packages/rest/src/rest-unclassified-fault-status.test.ts:230.

premise_false

API-F-01, the "getService is async" clause — the audit's premise is false and was NOT written. The real host contract is PluginContext.getService[T](name: string): T (packages/core/src/types.ts:36, doc comment @throws Error if service not found) — synchronous, and it throws. Measured on this base:

  • await ctx.getService in packages/plugins/**, excluding tests: 0 occurrences.
  • non-awaited ctx.getService( / ctx.getService[T](, same scope: 112.
  • the three app sites are ctx?.getService?.('manifest') with no await (packages/apps/{account,setup,studio}/src/index.ts:{60,55,68}).

The audit's evidence for "async" was recalc-endpoint.ts:52, which awaits — but that file's ctx is its own locally declared RecalcHostContext (:30-35) whose getService?: (name) => Promise<T> is a shim, not the host. That is precisely the defect API-C-02 was deleted for, so the skill states the true rule instead: getService is synchronous and throws, which is exactly why each name needs its own try and a() ?? b() in one try never reaches b.

The :532 "fix or unmark" item needs neither — the block is deleted with API-C-02, so no marker survives to prove or disprove anything.

PM assumptions — all six measured

#assumptionverdict
1skills/objectstack-api/** byte-identical a59f78d ↔ baseHOLDSgit diff a59f78d 96b627d1 -- skills/objectstack-api/ is empty; every audited span matched by content
2the frontmatter edit forces regeneration of BOTH generated filesHOLDScheck:skill-docs red on both before gen:skill-docs, green after; the .mdx pulled 20 docs-family gates into the union, re-derived and run
3the real PluginContext is unreachable from the os:check skills surfaceHOLDS, measured directly.SURFACES[0] resolves resolutionDir/selfPackages = packages/spec only (packages/spec/scripts/check-skill-examples.ts:526-532). Probed it: a temporary marked block importing PluginContext from @objectstack/core fails TS2307: Cannot find module '@objectstack/core'. Probe reverted and proven byte-identical (worktree blob hash == HEAD blob hash, git diff HEAD empty). ⇒ the F-01 block stays unmarked rather than earning a marker with a fabricated stand-in
4RestApiEndpointSchema 0 consumers · no plugin-rest-api package · no endpoints keyHOLDS — 0 hits outside packages/spec/src/api/plugin-rest-api* (positive control: the same grep for ApiEndpoint returns many); ls packages/plugins/ | grep -i rest empty; RestApiPluginConfig (packages/rest/src/rest-api-plugin.ts:95-105) is exactly {serverServiceName?, protocolServiceName?, kernelManagerServiceName?, api?}
5a heading in this file may be bound by check:skill-identifier-liveness Leg 2YES, and it is. Binding api-methods binds ## API Methods (Operations) to ApiMethod (scripts/check-skill-identifier-liveness.mjs:285-292). Fixed the author's way: the heading and all six primitives stay; only the derived rows moved. Gate green, 9 bindings, 0 ledgered gaps
6a false premise is skipped and listedapplied to the getService clause above

Token delta

filebeforeafterΔceiling
skills/objectstack-api/SKILL.md63114635−1,676 (−26.6%)6319, unchanged (headroom 8 → 1684)
skills/objectstack-api/evals/README.md5465460546 — untouched, API-H-01 deferred
skills/objectstack-api/references/_index.md8888880generator-owned, untouched
bundle, ratcheted (authored)171406169730−1,676171743

607 → 428 lines. No ceiling raised, no new file, no file deleted, and scripts/check-skills-token-ratchet.mjs is not edited.

The gap, itemised rather than smoothed. The dispatch target was −1,725 to −2,100; this lands at −1,676, short by 49 tokens (2.8%). It is not spread thin — it is two opposing errors in the audit's own estimates:

  • the three funded additions cost 239 tokens more than funded: F-01 271 actual vs +130 budgeted; F-02 162 vs +120; F-03 +96 net vs +40. Each was trimmed once already (F-01 from 407 tokens, F-02 from 250); trimming further would start dropping the load-bearing clauses each was funded to carry.
  • the deletions cut about 190 tokens more than the audit's per-span estimates, which is what absorbs most of that.

Closing the last 49 would mean cutting content no finding covers. Deliberately not done.

follow-up for objectstack-data / objectstack-platform

Both anchors are stronger than what this PR deleted, on every axis but one. Verified by heading on origin/claude/issue-14297-skills-data-optimization and origin/claude/issue-14299-skills-platform-optimization (what will merge):

  • objectstack-data/rules/datasources.md — byte-identical to origin/main on the data flight's branch; headings ## schemaMode — who owns the schema, ## Auto-connect (no onEnable), ## Credentials — fail-closed, ## Writes — double opt-in. ✅
  • objectstack-platform/SKILL.md## Driver Selection Guide — carries driver packages, class names, and the Turso "Cloud / EE onlyUnsupportedDriverError" caveat that the deleted api table omitted. ✅ Also ## Well-Known Plugin Names & Services and rules/service-registry.md both present. ✅
  • the one gap: neither anchor names the driver id vocabulary an author actually writes in defineDatasource({ driver: … })postgres, mysql, mongodb, sqlite, sqlite-wasm, turso, memory, and the mongo alias. The deleted api table did. Nothing is lost here — the pointer names the authoritative source, packages/spec/src/data/driver/config-registry.zod.ts:163 (resolveDriverId handles the aliases) — but a row in objectstack-data/rules/datasources.md would be the right home. Not filed as a card: it is one row inside a flight already in review; raising it here so that flight's reviewer can take it.

One file outside the declared surface, and why

scripts/role-word-baseline.jsoncheck:role-word went red on this branch with its ratchet-DOWN remedy, because API-C-03 deleted the file's single baselined occurrence of the reserved word (the Security Layers row | **RBAC** | Object | Role-based access control (profile → permissions) |). The gate names --update as the author's own path when a baselined file goes clean; leaving the entry would leave budget a later edit could spend silently. Baseline 43 → 42 files; the skills/objectstack-api/SKILL.md row is dropped, no other row moves. Committed separately.

Out-of-scope card filed

#14446 — declared ≠ enforced (ADR-0049): RealtimeEventType (packages/spec/src/api/realtime.zod.ts:33-40) spells record.* while the platform emits data.record.* (api/events.zod.ts:139-141), and SubscriptionSchema.filters is z.unknown().optional() (realtime.zod.ts:49). finding label, unassigned, no pm-state, no priority. Dedupe searched first — the four nearest cards (#4602, #4626, #4673, #9055) are all closed and none covers this pair.

Gates — head sha 19ee5853

Union re-derived after regeneration and again after the final commit: node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands42 commands (the .mdx output pulled in the docs family; the role-word baseline added 6 more: check:bash32-floor, check:cli-command-ids, check:entry-guard, check:parse-guard, check:pnpm-filter-targets, check:watch-hint-literal). All 42 run at 19ee5853; every exit code captured before any pipe.

41 green, 1 NOT MEASURED, 0 red.

  • node scripts/check-skills-token-ratchet.mjs✓ … 38 authored bundle file(s) within their ceilings
  • pnpm --filter @objectstack/spec check:skill-examples✅ 255 prose examples type-check across 3 surface(s) — every marked block parsed, so tsc ran the SEMANTIC pass on all of them (run under the shared verify lock; os-verify-lock: VERDICT command-exit 0). @objectstack/spec, @objectstack/client-react and @objectstack/formula closures built first, also under the lock — VERDICT command-exit 0 — so this gate could refuse rather than false-green.
  • pnpm check:skill-identifier-livenessOK — Leg 1: 488 citation(s) over 48 published file(s) …; Leg 2: 9 registered exhaustive section(s), 0 ledgered gap(s) (baseline was 500 citations; the drop is the deleted tables)
  • pnpm check:skill-compatibility✓ … 11 SKILL.md file(s) reconciled against 78 workspace packages
  • pnpm --filter @objectstack/spec check:skill-docs✅ Skill docs in sync
  • pnpm check:role-word after the ratchet-down
  • node scripts/check-nul-bytes.mjsOK (scanned 7875 text file(s) … no raw ASCII control bytes), plus a direct control-byte grep over the three edited files: no hits
  • NOT MEASURED:node scripts/check-test-completeness.mjs exits 3, its own "PREREQUISITE NOT MET" code — it needs a saved turbo run test log this run has no reason to produce. Its own text: "Nothing was measured … It is NOT a finding". CI supplies the log.

Two gates were exit-3 / exit-1 prerequisite states on the first pass and turned green once the closures were built, not by any edit: check:doc-formula-expressions + check:doc-security-posture (needed @objectstack/formula built) and check:docs (needed gen:schema, which build runs first).

Labels

skip-changeset — nothing released by any package changes. Checked against scripts/check-empty-changeset.mjs's own enumeration (:357: "It releases nothing (.github/, .claude/, skills/, docs/, content/, examples/…)"); this diff is skills/** + content/docs/** + one scripts/ ledger. needs:contract-review on both this PR and the card — the OCC contract, the error-ledger rule and the http.server mount timing are contract-semantics claims.

Stays draft: governed face.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1


Generated by Claude Code

…Schema example; teach http.server mount, the ADR-0112 code ledger and OCC
Optimization flight over skills/objectstack-api/SKILL.md (audit record posted
on the card). Shrink-only, additions paid by deletions in the same file.
DELETE / MERGE / REWRITE
API-E-01 the leading os:check example taught RestApiEndpointSchema: 0
consumers repo-wide, no plugin-rest-api package, and
RestApiPluginConfig has no `endpoints` key. The one live fact
(auth is the flat public + permissions pair) folded into the
auth section.
API-C-01 datasources + driver table -> objectstack-data rules/datasources.md
and objectstack-platform "Driver Selection Guide" (both carry more
than this file did, including the Turso Cloud/EE caveat).
API-C-02 inter-service communication -> objectstack-platform
rules/service-registry.md. Removes the `declare const kernel`
block that type-checked against a fabricated host shape.
API-C-03 Security Layers table named no authorable key -> one boundary line.
API-D-01 health/readiness response bodies -> one line (F-05, A-03).
API-D-02 Handler Status table, neutralised by its own callout.
API-D-03 Best Practices 1 and 4 (duplicate / no key, no gate).
API-D-04 Pitfalls 1, 2, 4 (FLS has no authorable spelling; the page sizes
match no platform constant; rate limiting is stated at D6).
API-D-05 the carve-out why-prose; the rule stays.
API-B-01 third rendering of "no nested auth block".
API-B-02 second gate invocation (and the `objectstack validate` spelling,
API-G-01) -> Verify your work states it once.
API-B-03 the apiMethods primitives/derived rule, stated 3x -> once. The
`## API Methods (Operations)` heading and all six ApiMethod members
stay: it is a registered exhaustive section (binding `api-methods`
in scripts/check-skill-identifier-liveness.mjs).
API-B-05 preamble restating the frontmatter.
API-F-04 environment-scoped routes / projectResolution, 0 usages (G-03).
API-F-05 ServiceInfo, a response shape with 0 usages -> one line.
API-F-06 the two declared-but-unenforced realtime notes (filed separately).
API-A-01 "When to Use This Skill" -> Skill Boundaries table, matching the
objectstack-data / objectstack-query form.
API-A-02 frontmatter drops the "versioning" promise: versioning.zod.ts has
zero consumers outside a pin test.
API-A-03 the description forbids the client seat; the body taught it.
ADD (funded)
API-F-01 the http.server code-mount example, the only code-route pattern the
repo ships. Left UNMARKED: `ctx` is @objectstack/core's
PluginContext and the skills os:check surface resolves
@objectstack/spec only, so a marker would need a locally declared
stand-in -- the same thing API-C-02 was deleted for.
Measured correction to the audit: ctx.getService is SYNCHRONOUS and
throws (0 awaited call sites in packages/plugins, 112 sync).
API-F-02 the ADR-0112 two-tier error-code ledger and the downstream
envelopeViolations + makeApiErrorSchema composition.
API-F-03 OCC stated with its real spellings: If-Match header or
expectedVersion body field, body wins, 409 CONCURRENT_UPDATE.
6311 -> 4635 tokens (ceiling 6319, unchanged); 607 -> 429 lines.
Part of #14304
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
…matter edit
Generator output only: `pnpm --filter @objectstack/spec gen:skill-docs` writes
both files from the SKILL.md frontmatter, and `check:skill-docs` fails without
this. The only change is API-A-02 dropping "versioning" from the description.
Part of #14304
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
`check:role-word` red on this branch with the ratchet-DOWN remedy: the file's
one baselined occurrence of the reserved word was the Security Layers row
`| **RBAC** | Object | Role-based access control (profile -> permissions) |`,
deleted by API-C-03. The gate names `--update` as the author's own path when a
baselined file goes clean, so the entry is dropped rather than left as budget a
later edit could spend silently. Baseline 43 -> 42 files; the objectstack-api
row is gone, no other row moves.
Part of #14304
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
@os-zhuang
os-zhuang marked this pull request as ready for review September 2, 2026 08:26
@os-zhuang
os-zhuang added this pull request to the merge queueSep 2, 2026
Merged via the queue into main with commit bae4088Sep 2, 2026
44 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-14304-skills-api-optimization branch September 2, 2026 09:03
os-zhuang added a commit that referenced this pull request Sep 2, 2026
…e base (#13823)
The published skill taught handlerStatus at this PR's base; main dropped that
teaching in the #14448 optimization flight (bae4088), so the changeset —
release-notes input — no longer claims an outstanding skills limb.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GDA48PuRFrHyRfdkBz8m21
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/mskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@os-litant@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

skills(api): optimization flight — RestApiEndpointSchema example and other packages' anchors cut, the apiMethods rule stated once, http.server mount / error ledger / OCC taught (net −1,676 tokens) - #14448

Merged
os-zhuang merged 3 commits into
mainfrom
claude/issue-14304-skills-api-optimization
Sep 2, 2026
Merged

Conversation

@os-litant

Copy link
Copy Markdown
Collaborator

Part of #14304

The audit record this implements is posted verbatim on the card. Every claim written into the file was re-verified at source on this branch's base; the file:line for each is below. evals/README.md is untouched (API-H-01 is deferred to #14296 item 2), so the card stays open — that is why the first line is Part of, not a closing keyword.

Per-item: 落点 | before | after

finding落点 (before)beforeafter
API-E-01SKILL.md:117-146 — the leading os:check exampleauthored RestApiEndpointSchema "via the REST API plugin"deleted. The one live fact (auth is the flat public + permissions pair, no name/request/response field) folded into Auth Configuration
API-C-01:472-510 Datasource Configuration + Supported Driversa defineDatasource example and a 7-row driver tabledeleted → one pointer: objectstack-data rules/datasources.md, objectstack-platform Driver Selection Guide, and data/driver/config-registry.zod.ts for the id vocabulary
API-C-02:513-538 Inter-Service CommunicationIDataEngine contract prose + a marked block whose declare const kernel fabricated the hostdeleted → the section's slot now carries the API-F-02 construct; service resolution points at objectstack-platform rules/service-registry.md
API-C-03:458-468 Security Layersa 4-row table naming no authorable key + a callout restating its own Description columndeleted → one boundary line under Authentication & Authorization
API-D-01 + API-F-05 + API-A-03:316-366 Service Discovery / Healtha ServiceInfoos:check example, a JSON health body, /ready proserewritten to 3 lines — all three are response surfaces, nothing to author
API-D-02:383-396 Handler Statusa 3-row table its own callout neutralised ("nothing reads it at runtime")deleted; the now-single-child ## Dispatcher & Routing wrapper collapses into ## Dispatcher Error Codes
API-B-01:419-429third rendering of "no nested auth block" + an unmarked duplicate fragmentdeleted, merged into one sentence that also carries the API-E-01 fold
API-B-02 + API-G-01:203-209a second objectstack validate gate block 384 lines from the firstdeleted — the gate is stated once, in Verify your work, in the bundle-dominant os spelling
API-B-03:65-71, :283-313, :559-563the apiMethods primitives/derived rule stated 3×once. Callout → 3 lines; derived table drops the 3 rows with no route and no derivation (history/restore/purge keep a one-line mention); Best Practice 6 stops restating it
API-B-05:22-28preamble restating the frontmatter above the folddeleted
API-A-01:31-39 "When to Use This Skill"6 bullets, 3 of which misrouteSkill Boundaries table, matching objectstack-data / objectstack-query
API-A-02frontmatter :3-12promises "batch/versioning contracts""batch contracts"versioning.zod.ts has zero consumers outside a pin test
API-A-03:83-94three /meta client query-param contracts2 lines saying they are client contracts nothing declares
API-D-03:544-547, :556-558Best Practices 1 and 4deleted (1 duplicates :273 and is wrong for the carve-out; 4 names no key and no gate)
API-D-04:569-576Pitfalls 1, 2, 4deleted — FLS has no authorable spelling in the bundle, the page sizes match no platform constant, rate limiting is already the D6 rule
API-D-05:191-198two why-paragraphs after the carve-out ruledeleted, rule kept
API-F-04 + API-G-03:275-279environment-scoped routes + projectResolution, 0 usagesdeleted (takes the retired project gloss with it)
API-F-06:404-411two declared-but-unenforced realtime notesdeleted from the skill; filed as #14446
API-G-02:481defineDatasource imported from the root barrelmoot — deleted with API-C-01
API-F-01(add)gap — :164 named http.server with no exampleone table cellnew ## Code routes: mounting on http.server` section
API-F-02(add)gap — :548-555frontmatter promised "error envelopes"; the ledger rule was absentnew ## Error Envelopes & the Code Ledger (ADR-0112)
API-F-03(add):575-576"use optimistic locking (version field)", naming no spellingthe two real spellings, body-wins, 409 CONCURRENT_UPDATE

The three funded additions — every claim, with its source

1. http.server code mount — verified against all three shipping sites (examples/app-showcase/src/system/server/recalc-endpoint.ts:48-118, packages/plugins/plugin-sharing/src/sharing-plugin.ts:787-790, packages/plugins/plugin-approvals/src/approvals-plugin.ts:353-356).

  • dual lookup readServer('http.server') ?? readServer('http-server'), canonical first — sharing-plugin.ts:787-790, approvals-plugin.ts:353-356; both carry the same comment that http.server is "the ONLY name present on all provider paths".
  • kernel:ready, not later — packages/spec/src/contracts/plugin-lifecycle-events.ts:70-91: listen() is deferred to kernel:listeningbecause "route registration in Hono … seals the matcher the first time a request is matched"; recalc-endpoint.ts:110-112 hooks kernel:ready.
  • the handler signature — RouteHandler = (req: IHttpRequest, res: IHttpResponse) at packages/spec/src/contracts/http-server.ts:108-111; IHttpResponse.status(code): IHttpResponse at :77 (so res.status(200).json(…) chains); IHttpServer.post at :216.
  • the block is NOT os:check-marked, deliberately. See "Assumption 3" below — this is measured, not assumed.

2. ADR-0112 error-code ledgerpackages/spec/src/api/error-code-ledger.zod.ts:6-56 states the two tiers, "An unregistered code fails schema parse — which fails the envelope conformance suites — which fails CI", the framework-packages-only scope rule (#4805, maintainer ruling 2026-08-03 re-confirmed 2026-08-09), and the downstream composition. Functions re-located by content on this base: makeApiErrorSchema at packages/spec/src/api/contract.zod.ts:146, envelopeViolations at :215.

3. OCCpackages/rest/src/rest-server.ts:7710-7727 is the PATCH /api/v1/data/:object/:id route: If-Match header or expectedVersion body field, const expectedVersion = bodyVersion ?? ifMatchHeader (body wins), and the field is stripped from the write payload. The token semantics, the 409 and the "" refusal are the spec's own .describe() at packages/spec/src/api/protocol.zod.ts:2097-2102. CONCURRENT_UPDATE is registered at packages/spec/src/api/error-code-ledger.zod.ts:168 and pinned to 409 at packages/rest/src/rest-unclassified-fault-status.test.ts:230.

premise_false

API-F-01, the "getService is async" clause — the audit's premise is false and was NOT written. The real host contract is PluginContext.getService[T](name: string): T (packages/core/src/types.ts:36, doc comment @throws Error if service not found) — synchronous, and it throws. Measured on this base:

  • await ctx.getService in packages/plugins/**, excluding tests: 0 occurrences.
  • non-awaited ctx.getService( / ctx.getService[T](, same scope: 112.
  • the three app sites are ctx?.getService?.('manifest') with no await (packages/apps/{account,setup,studio}/src/index.ts:{60,55,68}).

The audit's evidence for "async" was recalc-endpoint.ts:52, which awaits — but that file's ctx is its own locally declared RecalcHostContext (:30-35) whose getService?: (name) => Promise<T> is a shim, not the host. That is precisely the defect API-C-02 was deleted for, so the skill states the true rule instead: getService is synchronous and throws, which is exactly why each name needs its own try and a() ?? b() in one try never reaches b.

The :532 "fix or unmark" item needs neither — the block is deleted with API-C-02, so no marker survives to prove or disprove anything.

PM assumptions — all six measured

#assumptionverdict
1skills/objectstack-api/** byte-identical a59f78d ↔ baseHOLDSgit diff a59f78d 96b627d1 -- skills/objectstack-api/ is empty; every audited span matched by content
2the frontmatter edit forces regeneration of BOTH generated filesHOLDScheck:skill-docs red on both before gen:skill-docs, green after; the .mdx pulled 20 docs-family gates into the union, re-derived and run
3the real PluginContext is unreachable from the os:check skills surfaceHOLDS, measured directly.SURFACES[0] resolves resolutionDir/selfPackages = packages/spec only (packages/spec/scripts/check-skill-examples.ts:526-532). Probed it: a temporary marked block importing PluginContext from @objectstack/core fails TS2307: Cannot find module '@objectstack/core'. Probe reverted and proven byte-identical (worktree blob hash == HEAD blob hash, git diff HEAD empty). ⇒ the F-01 block stays unmarked rather than earning a marker with a fabricated stand-in
4RestApiEndpointSchema 0 consumers · no plugin-rest-api package · no endpoints keyHOLDS — 0 hits outside packages/spec/src/api/plugin-rest-api* (positive control: the same grep for ApiEndpoint returns many); ls packages/plugins/ | grep -i rest empty; RestApiPluginConfig (packages/rest/src/rest-api-plugin.ts:95-105) is exactly {serverServiceName?, protocolServiceName?, kernelManagerServiceName?, api?}
5a heading in this file may be bound by check:skill-identifier-liveness Leg 2YES, and it is. Binding api-methods binds ## API Methods (Operations) to ApiMethod (scripts/check-skill-identifier-liveness.mjs:285-292). Fixed the author's way: the heading and all six primitives stay; only the derived rows moved. Gate green, 9 bindings, 0 ledgered gaps
6a false premise is skipped and listedapplied to the getService clause above

Token delta

filebeforeafterΔceiling
skills/objectstack-api/SKILL.md63114635−1,676 (−26.6%)6319, unchanged (headroom 8 → 1684)
skills/objectstack-api/evals/README.md5465460546 — untouched, API-H-01 deferred
skills/objectstack-api/references/_index.md8888880generator-owned, untouched
bundle, ratcheted (authored)171406169730−1,676171743

607 → 428 lines. No ceiling raised, no new file, no file deleted, and scripts/check-skills-token-ratchet.mjs is not edited.

The gap, itemised rather than smoothed. The dispatch target was −1,725 to −2,100; this lands at −1,676, short by 49 tokens (2.8%). It is not spread thin — it is two opposing errors in the audit's own estimates:

  • the three funded additions cost 239 tokens more than funded: F-01 271 actual vs +130 budgeted; F-02 162 vs +120; F-03 +96 net vs +40. Each was trimmed once already (F-01 from 407 tokens, F-02 from 250); trimming further would start dropping the load-bearing clauses each was funded to carry.
  • the deletions cut about 190 tokens more than the audit's per-span estimates, which is what absorbs most of that.

Closing the last 49 would mean cutting content no finding covers. Deliberately not done.

follow-up for objectstack-data / objectstack-platform

Both anchors are stronger than what this PR deleted, on every axis but one. Verified by heading on origin/claude/issue-14297-skills-data-optimization and origin/claude/issue-14299-skills-platform-optimization (what will merge):

  • objectstack-data/rules/datasources.md — byte-identical to origin/main on the data flight's branch; headings ## schemaMode — who owns the schema, ## Auto-connect (no onEnable), ## Credentials — fail-closed, ## Writes — double opt-in. ✅
  • objectstack-platform/SKILL.md## Driver Selection Guide — carries driver packages, class names, and the Turso "Cloud / EE onlyUnsupportedDriverError" caveat that the deleted api table omitted. ✅ Also ## Well-Known Plugin Names & Services and rules/service-registry.md both present. ✅
  • the one gap: neither anchor names the driver id vocabulary an author actually writes in defineDatasource({ driver: … })postgres, mysql, mongodb, sqlite, sqlite-wasm, turso, memory, and the mongo alias. The deleted api table did. Nothing is lost here — the pointer names the authoritative source, packages/spec/src/data/driver/config-registry.zod.ts:163 (resolveDriverId handles the aliases) — but a row in objectstack-data/rules/datasources.md would be the right home. Not filed as a card: it is one row inside a flight already in review; raising it here so that flight's reviewer can take it.

One file outside the declared surface, and why

scripts/role-word-baseline.jsoncheck:role-word went red on this branch with its ratchet-DOWN remedy, because API-C-03 deleted the file's single baselined occurrence of the reserved word (the Security Layers row | **RBAC** | Object | Role-based access control (profile → permissions) |). The gate names --update as the author's own path when a baselined file goes clean; leaving the entry would leave budget a later edit could spend silently. Baseline 43 → 42 files; the skills/objectstack-api/SKILL.md row is dropped, no other row moves. Committed separately.

Out-of-scope card filed

#14446 — declared ≠ enforced (ADR-0049): RealtimeEventType (packages/spec/src/api/realtime.zod.ts:33-40) spells record.* while the platform emits data.record.* (api/events.zod.ts:139-141), and SubscriptionSchema.filters is z.unknown().optional() (realtime.zod.ts:49). finding label, unassigned, no pm-state, no priority. Dedupe searched first — the four nearest cards (#4602, #4626, #4673, #9055) are all closed and none covers this pair.

Gates — head sha 19ee5853

Union re-derived after regeneration and again after the final commit: node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands42 commands (the .mdx output pulled in the docs family; the role-word baseline added 6 more: check:bash32-floor, check:cli-command-ids, check:entry-guard, check:parse-guard, check:pnpm-filter-targets, check:watch-hint-literal). All 42 run at 19ee5853; every exit code captured before any pipe.

41 green, 1 NOT MEASURED, 0 red.

  • node scripts/check-skills-token-ratchet.mjs✓ … 38 authored bundle file(s) within their ceilings
  • pnpm --filter @objectstack/spec check:skill-examples✅ 255 prose examples type-check across 3 surface(s) — every marked block parsed, so tsc ran the SEMANTIC pass on all of them (run under the shared verify lock; os-verify-lock: VERDICT command-exit 0). @objectstack/spec, @objectstack/client-react and @objectstack/formula closures built first, also under the lock — VERDICT command-exit 0 — so this gate could refuse rather than false-green.
  • pnpm check:skill-identifier-livenessOK — Leg 1: 488 citation(s) over 48 published file(s) …; Leg 2: 9 registered exhaustive section(s), 0 ledgered gap(s) (baseline was 500 citations; the drop is the deleted tables)
  • pnpm check:skill-compatibility✓ … 11 SKILL.md file(s) reconciled against 78 workspace packages
  • pnpm --filter @objectstack/spec check:skill-docs✅ Skill docs in sync
  • pnpm check:role-word after the ratchet-down
  • node scripts/check-nul-bytes.mjsOK (scanned 7875 text file(s) … no raw ASCII control bytes), plus a direct control-byte grep over the three edited files: no hits
  • NOT MEASURED:node scripts/check-test-completeness.mjs exits 3, its own "PREREQUISITE NOT MET" code — it needs a saved turbo run test log this run has no reason to produce. Its own text: "Nothing was measured … It is NOT a finding". CI supplies the log.

Two gates were exit-3 / exit-1 prerequisite states on the first pass and turned green once the closures were built, not by any edit: check:doc-formula-expressions + check:doc-security-posture (needed @objectstack/formula built) and check:docs (needed gen:schema, which build runs first).

Labels

skip-changeset — nothing released by any package changes. Checked against scripts/check-empty-changeset.mjs's own enumeration (:357: "It releases nothing (.github/, .claude/, skills/, docs/, content/, examples/…)"); this diff is skills/** + content/docs/** + one scripts/ ledger. needs:contract-review on both this PR and the card — the OCC contract, the error-ledger rule and the http.server mount timing are contract-semantics claims.

Stays draft: governed face.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1


Generated by Claude Code

…Schema example; teach http.server mount, the ADR-0112 code ledger and OCC
Optimization flight over skills/objectstack-api/SKILL.md (audit record posted
on the card). Shrink-only, additions paid by deletions in the same file.
DELETE / MERGE / REWRITE
API-E-01 the leading os:check example taught RestApiEndpointSchema: 0
consumers repo-wide, no plugin-rest-api package, and
RestApiPluginConfig has no `endpoints` key. The one live fact
(auth is the flat public + permissions pair) folded into the
auth section.
API-C-01 datasources + driver table -> objectstack-data rules/datasources.md
and objectstack-platform "Driver Selection Guide" (both carry more
than this file did, including the Turso Cloud/EE caveat).
API-C-02 inter-service communication -> objectstack-platform
rules/service-registry.md. Removes the `declare const kernel`
block that type-checked against a fabricated host shape.
API-C-03 Security Layers table named no authorable key -> one boundary line.
API-D-01 health/readiness response bodies -> one line (F-05, A-03).
API-D-02 Handler Status table, neutralised by its own callout.
API-D-03 Best Practices 1 and 4 (duplicate / no key, no gate).
API-D-04 Pitfalls 1, 2, 4 (FLS has no authorable spelling; the page sizes
match no platform constant; rate limiting is stated at D6).
API-D-05 the carve-out why-prose; the rule stays.
API-B-01 third rendering of "no nested auth block".
API-B-02 second gate invocation (and the `objectstack validate` spelling,
API-G-01) -> Verify your work states it once.
API-B-03 the apiMethods primitives/derived rule, stated 3x -> once. The
`## API Methods (Operations)` heading and all six ApiMethod members
stay: it is a registered exhaustive section (binding `api-methods`
in scripts/check-skill-identifier-liveness.mjs).
API-B-05 preamble restating the frontmatter.
API-F-04 environment-scoped routes / projectResolution, 0 usages (G-03).
API-F-05 ServiceInfo, a response shape with 0 usages -> one line.
API-F-06 the two declared-but-unenforced realtime notes (filed separately).
API-A-01 "When to Use This Skill" -> Skill Boundaries table, matching the
objectstack-data / objectstack-query form.
API-A-02 frontmatter drops the "versioning" promise: versioning.zod.ts has
zero consumers outside a pin test.
API-A-03 the description forbids the client seat; the body taught it.
ADD (funded)
API-F-01 the http.server code-mount example, the only code-route pattern the
repo ships. Left UNMARKED: `ctx` is @objectstack/core's
PluginContext and the skills os:check surface resolves
@objectstack/spec only, so a marker would need a locally declared
stand-in -- the same thing API-C-02 was deleted for.
Measured correction to the audit: ctx.getService is SYNCHRONOUS and
throws (0 awaited call sites in packages/plugins, 112 sync).
API-F-02 the ADR-0112 two-tier error-code ledger and the downstream
envelopeViolations + makeApiErrorSchema composition.
API-F-03 OCC stated with its real spellings: If-Match header or
expectedVersion body field, body wins, 409 CONCURRENT_UPDATE.
6311 -> 4635 tokens (ceiling 6319, unchanged); 607 -> 429 lines.
Part of #14304
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
…matter edit
Generator output only: `pnpm --filter @objectstack/spec gen:skill-docs` writes
both files from the SKILL.md frontmatter, and `check:skill-docs` fails without
this. The only change is API-A-02 dropping "versioning" from the description.
Part of #14304
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
`check:role-word` red on this branch with the ratchet-DOWN remedy: the file's
one baselined occurrence of the reserved word was the Security Layers row
`| **RBAC** | Object | Role-based access control (profile -> permissions) |`,
deleted by API-C-03. The gate names `--update` as the author's own path when a
baselined file goes clean, so the entry is dropped rather than left as budget a
later edit could spend silently. Baseline 43 -> 42 files; the objectstack-api
row is gone, no other row moves.
Part of #14304
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
@os-zhuang
os-zhuang marked this pull request as ready for review September 2, 2026 08:26
@os-zhuang
os-zhuang added this pull request to the merge queueSep 2, 2026
Merged via the queue into main with commit bae4088Sep 2, 2026
44 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-14304-skills-api-optimization branch September 2, 2026 09:03
os-zhuang added a commit that referenced this pull request Sep 2, 2026
…e base (#13823)
The published skill taught handlerStatus at this PR's base; main dropped that
teaching in the #14448 optimization flight (bae4088), so the changeset —
release-notes input — no longer claims an outstanding skills limb.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GDA48PuRFrHyRfdkBz8m21
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/mskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@os-litant@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

skills(api): optimization flight — RestApiEndpointSchema example and other packages' anchors cut, the apiMethods rule stated once, http.server mount / error ledger / OCC taught (net −1,676 tokens) - #14448

Merged
os-zhuang merged 3 commits into
mainfrom
claude/issue-14304-skills-api-optimization
Sep 2, 2026
Merged

Conversation

@os-litant

Copy link
Copy Markdown
Collaborator

Part of #14304

The audit record this implements is posted verbatim on the card. Every claim written into the file was re-verified at source on this branch's base; the file:line for each is below. evals/README.md is untouched (API-H-01 is deferred to #14296 item 2), so the card stays open — that is why the first line is Part of, not a closing keyword.

Per-item: 落点 | before | after

finding落点 (before)beforeafter
API-E-01SKILL.md:117-146 — the leading os:check exampleauthored RestApiEndpointSchema "via the REST API plugin"deleted. The one live fact (auth is the flat public + permissions pair, no name/request/response field) folded into Auth Configuration
API-C-01:472-510 Datasource Configuration + Supported Driversa defineDatasource example and a 7-row driver tabledeleted → one pointer: objectstack-data rules/datasources.md, objectstack-platform Driver Selection Guide, and data/driver/config-registry.zod.ts for the id vocabulary
API-C-02:513-538 Inter-Service CommunicationIDataEngine contract prose + a marked block whose declare const kernel fabricated the hostdeleted → the section's slot now carries the API-F-02 construct; service resolution points at objectstack-platform rules/service-registry.md
API-C-03:458-468 Security Layersa 4-row table naming no authorable key + a callout restating its own Description columndeleted → one boundary line under Authentication & Authorization
API-D-01 + API-F-05 + API-A-03:316-366 Service Discovery / Healtha ServiceInfoos:check example, a JSON health body, /ready proserewritten to 3 lines — all three are response surfaces, nothing to author
API-D-02:383-396 Handler Statusa 3-row table its own callout neutralised ("nothing reads it at runtime")deleted; the now-single-child ## Dispatcher & Routing wrapper collapses into ## Dispatcher Error Codes
API-B-01:419-429third rendering of "no nested auth block" + an unmarked duplicate fragmentdeleted, merged into one sentence that also carries the API-E-01 fold
API-B-02 + API-G-01:203-209a second objectstack validate gate block 384 lines from the firstdeleted — the gate is stated once, in Verify your work, in the bundle-dominant os spelling
API-B-03:65-71, :283-313, :559-563the apiMethods primitives/derived rule stated 3×once. Callout → 3 lines; derived table drops the 3 rows with no route and no derivation (history/restore/purge keep a one-line mention); Best Practice 6 stops restating it
API-B-05:22-28preamble restating the frontmatter above the folddeleted
API-A-01:31-39 "When to Use This Skill"6 bullets, 3 of which misrouteSkill Boundaries table, matching objectstack-data / objectstack-query
API-A-02frontmatter :3-12promises "batch/versioning contracts""batch contracts"versioning.zod.ts has zero consumers outside a pin test
API-A-03:83-94three /meta client query-param contracts2 lines saying they are client contracts nothing declares
API-D-03:544-547, :556-558Best Practices 1 and 4deleted (1 duplicates :273 and is wrong for the carve-out; 4 names no key and no gate)
API-D-04:569-576Pitfalls 1, 2, 4deleted — FLS has no authorable spelling in the bundle, the page sizes match no platform constant, rate limiting is already the D6 rule
API-D-05:191-198two why-paragraphs after the carve-out ruledeleted, rule kept
API-F-04 + API-G-03:275-279environment-scoped routes + projectResolution, 0 usagesdeleted (takes the retired project gloss with it)
API-F-06:404-411two declared-but-unenforced realtime notesdeleted from the skill; filed as #14446
API-G-02:481defineDatasource imported from the root barrelmoot — deleted with API-C-01
API-F-01(add)gap — :164 named http.server with no exampleone table cellnew ## Code routes: mounting on http.server` section
API-F-02(add)gap — :548-555frontmatter promised "error envelopes"; the ledger rule was absentnew ## Error Envelopes & the Code Ledger (ADR-0112)
API-F-03(add):575-576"use optimistic locking (version field)", naming no spellingthe two real spellings, body-wins, 409 CONCURRENT_UPDATE

The three funded additions — every claim, with its source

1. http.server code mount — verified against all three shipping sites (examples/app-showcase/src/system/server/recalc-endpoint.ts:48-118, packages/plugins/plugin-sharing/src/sharing-plugin.ts:787-790, packages/plugins/plugin-approvals/src/approvals-plugin.ts:353-356).

  • dual lookup readServer('http.server') ?? readServer('http-server'), canonical first — sharing-plugin.ts:787-790, approvals-plugin.ts:353-356; both carry the same comment that http.server is "the ONLY name present on all provider paths".
  • kernel:ready, not later — packages/spec/src/contracts/plugin-lifecycle-events.ts:70-91: listen() is deferred to kernel:listeningbecause "route registration in Hono … seals the matcher the first time a request is matched"; recalc-endpoint.ts:110-112 hooks kernel:ready.
  • the handler signature — RouteHandler = (req: IHttpRequest, res: IHttpResponse) at packages/spec/src/contracts/http-server.ts:108-111; IHttpResponse.status(code): IHttpResponse at :77 (so res.status(200).json(…) chains); IHttpServer.post at :216.
  • the block is NOT os:check-marked, deliberately. See "Assumption 3" below — this is measured, not assumed.

2. ADR-0112 error-code ledgerpackages/spec/src/api/error-code-ledger.zod.ts:6-56 states the two tiers, "An unregistered code fails schema parse — which fails the envelope conformance suites — which fails CI", the framework-packages-only scope rule (#4805, maintainer ruling 2026-08-03 re-confirmed 2026-08-09), and the downstream composition. Functions re-located by content on this base: makeApiErrorSchema at packages/spec/src/api/contract.zod.ts:146, envelopeViolations at :215.

3. OCCpackages/rest/src/rest-server.ts:7710-7727 is the PATCH /api/v1/data/:object/:id route: If-Match header or expectedVersion body field, const expectedVersion = bodyVersion ?? ifMatchHeader (body wins), and the field is stripped from the write payload. The token semantics, the 409 and the "" refusal are the spec's own .describe() at packages/spec/src/api/protocol.zod.ts:2097-2102. CONCURRENT_UPDATE is registered at packages/spec/src/api/error-code-ledger.zod.ts:168 and pinned to 409 at packages/rest/src/rest-unclassified-fault-status.test.ts:230.

premise_false

API-F-01, the "getService is async" clause — the audit's premise is false and was NOT written. The real host contract is PluginContext.getService[T](name: string): T (packages/core/src/types.ts:36, doc comment @throws Error if service not found) — synchronous, and it throws. Measured on this base:

  • await ctx.getService in packages/plugins/**, excluding tests: 0 occurrences.
  • non-awaited ctx.getService( / ctx.getService[T](, same scope: 112.
  • the three app sites are ctx?.getService?.('manifest') with no await (packages/apps/{account,setup,studio}/src/index.ts:{60,55,68}).

The audit's evidence for "async" was recalc-endpoint.ts:52, which awaits — but that file's ctx is its own locally declared RecalcHostContext (:30-35) whose getService?: (name) => Promise<T> is a shim, not the host. That is precisely the defect API-C-02 was deleted for, so the skill states the true rule instead: getService is synchronous and throws, which is exactly why each name needs its own try and a() ?? b() in one try never reaches b.

The :532 "fix or unmark" item needs neither — the block is deleted with API-C-02, so no marker survives to prove or disprove anything.

PM assumptions — all six measured

#assumptionverdict
1skills/objectstack-api/** byte-identical a59f78d ↔ baseHOLDSgit diff a59f78d 96b627d1 -- skills/objectstack-api/ is empty; every audited span matched by content
2the frontmatter edit forces regeneration of BOTH generated filesHOLDScheck:skill-docs red on both before gen:skill-docs, green after; the .mdx pulled 20 docs-family gates into the union, re-derived and run
3the real PluginContext is unreachable from the os:check skills surfaceHOLDS, measured directly.SURFACES[0] resolves resolutionDir/selfPackages = packages/spec only (packages/spec/scripts/check-skill-examples.ts:526-532). Probed it: a temporary marked block importing PluginContext from @objectstack/core fails TS2307: Cannot find module '@objectstack/core'. Probe reverted and proven byte-identical (worktree blob hash == HEAD blob hash, git diff HEAD empty). ⇒ the F-01 block stays unmarked rather than earning a marker with a fabricated stand-in
4RestApiEndpointSchema 0 consumers · no plugin-rest-api package · no endpoints keyHOLDS — 0 hits outside packages/spec/src/api/plugin-rest-api* (positive control: the same grep for ApiEndpoint returns many); ls packages/plugins/ | grep -i rest empty; RestApiPluginConfig (packages/rest/src/rest-api-plugin.ts:95-105) is exactly {serverServiceName?, protocolServiceName?, kernelManagerServiceName?, api?}
5a heading in this file may be bound by check:skill-identifier-liveness Leg 2YES, and it is. Binding api-methods binds ## API Methods (Operations) to ApiMethod (scripts/check-skill-identifier-liveness.mjs:285-292). Fixed the author's way: the heading and all six primitives stay; only the derived rows moved. Gate green, 9 bindings, 0 ledgered gaps
6a false premise is skipped and listedapplied to the getService clause above

Token delta

filebeforeafterΔceiling
skills/objectstack-api/SKILL.md63114635−1,676 (−26.6%)6319, unchanged (headroom 8 → 1684)
skills/objectstack-api/evals/README.md5465460546 — untouched, API-H-01 deferred
skills/objectstack-api/references/_index.md8888880generator-owned, untouched
bundle, ratcheted (authored)171406169730−1,676171743

607 → 428 lines. No ceiling raised, no new file, no file deleted, and scripts/check-skills-token-ratchet.mjs is not edited.

The gap, itemised rather than smoothed. The dispatch target was −1,725 to −2,100; this lands at −1,676, short by 49 tokens (2.8%). It is not spread thin — it is two opposing errors in the audit's own estimates:

  • the three funded additions cost 239 tokens more than funded: F-01 271 actual vs +130 budgeted; F-02 162 vs +120; F-03 +96 net vs +40. Each was trimmed once already (F-01 from 407 tokens, F-02 from 250); trimming further would start dropping the load-bearing clauses each was funded to carry.
  • the deletions cut about 190 tokens more than the audit's per-span estimates, which is what absorbs most of that.

Closing the last 49 would mean cutting content no finding covers. Deliberately not done.

follow-up for objectstack-data / objectstack-platform

Both anchors are stronger than what this PR deleted, on every axis but one. Verified by heading on origin/claude/issue-14297-skills-data-optimization and origin/claude/issue-14299-skills-platform-optimization (what will merge):

  • objectstack-data/rules/datasources.md — byte-identical to origin/main on the data flight's branch; headings ## schemaMode — who owns the schema, ## Auto-connect (no onEnable), ## Credentials — fail-closed, ## Writes — double opt-in. ✅
  • objectstack-platform/SKILL.md## Driver Selection Guide — carries driver packages, class names, and the Turso "Cloud / EE onlyUnsupportedDriverError" caveat that the deleted api table omitted. ✅ Also ## Well-Known Plugin Names & Services and rules/service-registry.md both present. ✅
  • the one gap: neither anchor names the driver id vocabulary an author actually writes in defineDatasource({ driver: … })postgres, mysql, mongodb, sqlite, sqlite-wasm, turso, memory, and the mongo alias. The deleted api table did. Nothing is lost here — the pointer names the authoritative source, packages/spec/src/data/driver/config-registry.zod.ts:163 (resolveDriverId handles the aliases) — but a row in objectstack-data/rules/datasources.md would be the right home. Not filed as a card: it is one row inside a flight already in review; raising it here so that flight's reviewer can take it.

One file outside the declared surface, and why

scripts/role-word-baseline.jsoncheck:role-word went red on this branch with its ratchet-DOWN remedy, because API-C-03 deleted the file's single baselined occurrence of the reserved word (the Security Layers row | **RBAC** | Object | Role-based access control (profile → permissions) |). The gate names --update as the author's own path when a baselined file goes clean; leaving the entry would leave budget a later edit could spend silently. Baseline 43 → 42 files; the skills/objectstack-api/SKILL.md row is dropped, no other row moves. Committed separately.

Out-of-scope card filed

#14446 — declared ≠ enforced (ADR-0049): RealtimeEventType (packages/spec/src/api/realtime.zod.ts:33-40) spells record.* while the platform emits data.record.* (api/events.zod.ts:139-141), and SubscriptionSchema.filters is z.unknown().optional() (realtime.zod.ts:49). finding label, unassigned, no pm-state, no priority. Dedupe searched first — the four nearest cards (#4602, #4626, #4673, #9055) are all closed and none covers this pair.

Gates — head sha 19ee5853

Union re-derived after regeneration and again after the final commit: node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands42 commands (the .mdx output pulled in the docs family; the role-word baseline added 6 more: check:bash32-floor, check:cli-command-ids, check:entry-guard, check:parse-guard, check:pnpm-filter-targets, check:watch-hint-literal). All 42 run at 19ee5853; every exit code captured before any pipe.

41 green, 1 NOT MEASURED, 0 red.

  • node scripts/check-skills-token-ratchet.mjs✓ … 38 authored bundle file(s) within their ceilings
  • pnpm --filter @objectstack/spec check:skill-examples✅ 255 prose examples type-check across 3 surface(s) — every marked block parsed, so tsc ran the SEMANTIC pass on all of them (run under the shared verify lock; os-verify-lock: VERDICT command-exit 0). @objectstack/spec, @objectstack/client-react and @objectstack/formula closures built first, also under the lock — VERDICT command-exit 0 — so this gate could refuse rather than false-green.
  • pnpm check:skill-identifier-livenessOK — Leg 1: 488 citation(s) over 48 published file(s) …; Leg 2: 9 registered exhaustive section(s), 0 ledgered gap(s) (baseline was 500 citations; the drop is the deleted tables)
  • pnpm check:skill-compatibility✓ … 11 SKILL.md file(s) reconciled against 78 workspace packages
  • pnpm --filter @objectstack/spec check:skill-docs✅ Skill docs in sync
  • pnpm check:role-word after the ratchet-down
  • node scripts/check-nul-bytes.mjsOK (scanned 7875 text file(s) … no raw ASCII control bytes), plus a direct control-byte grep over the three edited files: no hits
  • NOT MEASURED:node scripts/check-test-completeness.mjs exits 3, its own "PREREQUISITE NOT MET" code — it needs a saved turbo run test log this run has no reason to produce. Its own text: "Nothing was measured … It is NOT a finding". CI supplies the log.

Two gates were exit-3 / exit-1 prerequisite states on the first pass and turned green once the closures were built, not by any edit: check:doc-formula-expressions + check:doc-security-posture (needed @objectstack/formula built) and check:docs (needed gen:schema, which build runs first).

Labels

skip-changeset — nothing released by any package changes. Checked against scripts/check-empty-changeset.mjs's own enumeration (:357: "It releases nothing (.github/, .claude/, skills/, docs/, content/, examples/…)"); this diff is skills/** + content/docs/** + one scripts/ ledger. needs:contract-review on both this PR and the card — the OCC contract, the error-ledger rule and the http.server mount timing are contract-semantics claims.

Stays draft: governed face.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1


Generated by Claude Code

…Schema example; teach http.server mount, the ADR-0112 code ledger and OCC
Optimization flight over skills/objectstack-api/SKILL.md (audit record posted
on the card). Shrink-only, additions paid by deletions in the same file.
DELETE / MERGE / REWRITE
API-E-01 the leading os:check example taught RestApiEndpointSchema: 0
consumers repo-wide, no plugin-rest-api package, and
RestApiPluginConfig has no `endpoints` key. The one live fact
(auth is the flat public + permissions pair) folded into the
auth section.
API-C-01 datasources + driver table -> objectstack-data rules/datasources.md
and objectstack-platform "Driver Selection Guide" (both carry more
than this file did, including the Turso Cloud/EE caveat).
API-C-02 inter-service communication -> objectstack-platform
rules/service-registry.md. Removes the `declare const kernel`
block that type-checked against a fabricated host shape.
API-C-03 Security Layers table named no authorable key -> one boundary line.
API-D-01 health/readiness response bodies -> one line (F-05, A-03).
API-D-02 Handler Status table, neutralised by its own callout.
API-D-03 Best Practices 1 and 4 (duplicate / no key, no gate).
API-D-04 Pitfalls 1, 2, 4 (FLS has no authorable spelling; the page sizes
match no platform constant; rate limiting is stated at D6).
API-D-05 the carve-out why-prose; the rule stays.
API-B-01 third rendering of "no nested auth block".
API-B-02 second gate invocation (and the `objectstack validate` spelling,
API-G-01) -> Verify your work states it once.
API-B-03 the apiMethods primitives/derived rule, stated 3x -> once. The
`## API Methods (Operations)` heading and all six ApiMethod members
stay: it is a registered exhaustive section (binding `api-methods`
in scripts/check-skill-identifier-liveness.mjs).
API-B-05 preamble restating the frontmatter.
API-F-04 environment-scoped routes / projectResolution, 0 usages (G-03).
API-F-05 ServiceInfo, a response shape with 0 usages -> one line.
API-F-06 the two declared-but-unenforced realtime notes (filed separately).
API-A-01 "When to Use This Skill" -> Skill Boundaries table, matching the
objectstack-data / objectstack-query form.
API-A-02 frontmatter drops the "versioning" promise: versioning.zod.ts has
zero consumers outside a pin test.
API-A-03 the description forbids the client seat; the body taught it.
ADD (funded)
API-F-01 the http.server code-mount example, the only code-route pattern the
repo ships. Left UNMARKED: `ctx` is @objectstack/core's
PluginContext and the skills os:check surface resolves
@objectstack/spec only, so a marker would need a locally declared
stand-in -- the same thing API-C-02 was deleted for.
Measured correction to the audit: ctx.getService is SYNCHRONOUS and
throws (0 awaited call sites in packages/plugins, 112 sync).
API-F-02 the ADR-0112 two-tier error-code ledger and the downstream
envelopeViolations + makeApiErrorSchema composition.
API-F-03 OCC stated with its real spellings: If-Match header or
expectedVersion body field, body wins, 409 CONCURRENT_UPDATE.
6311 -> 4635 tokens (ceiling 6319, unchanged); 607 -> 429 lines.
Part of #14304
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
…matter edit
Generator output only: `pnpm --filter @objectstack/spec gen:skill-docs` writes
both files from the SKILL.md frontmatter, and `check:skill-docs` fails without
this. The only change is API-A-02 dropping "versioning" from the description.
Part of #14304
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
`check:role-word` red on this branch with the ratchet-DOWN remedy: the file's
one baselined occurrence of the reserved word was the Security Layers row
`| **RBAC** | Object | Role-based access control (profile -> permissions) |`,
deleted by API-C-03. The gate names `--update` as the author's own path when a
baselined file goes clean, so the entry is dropped rather than left as budget a
later edit could spend silently. Baseline 43 -> 42 files; the objectstack-api
row is gone, no other row moves.
Part of #14304
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
@os-zhuang
os-zhuang marked this pull request as ready for review September 2, 2026 08:26
@os-zhuang
os-zhuang added this pull request to the merge queueSep 2, 2026
Merged via the queue into main with commit bae4088Sep 2, 2026
44 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-14304-skills-api-optimization branch September 2, 2026 09:03
os-zhuang added a commit that referenced this pull request Sep 2, 2026
…e base (#13823)
The published skill taught handlerStatus at this PR's base; main dropped that
teaching in the #14448 optimization flight (bae4088), so the changeset —
release-notes input — no longer claims an outstanding skills limb.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GDA48PuRFrHyRfdkBz8m21
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/mskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@os-litant@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

skills(api): optimization flight — RestApiEndpointSchema example and other packages' anchors cut, the apiMethods rule stated once, http.server mount / error ledger / OCC taught (net −1,676 tokens) - #14448

Merged
os-zhuang merged 3 commits into
mainfrom
claude/issue-14304-skills-api-optimization
Sep 2, 2026
Merged

Conversation

@os-litant

Copy link
Copy Markdown
Collaborator

Part of #14304

The audit record this implements is posted verbatim on the card. Every claim written into the file was re-verified at source on this branch's base; the file:line for each is below. evals/README.md is untouched (API-H-01 is deferred to #14296 item 2), so the card stays open — that is why the first line is Part of, not a closing keyword.

Per-item: 落点 | before | after

finding落点 (before)beforeafter
API-E-01SKILL.md:117-146 — the leading os:check exampleauthored RestApiEndpointSchema "via the REST API plugin"deleted. The one live fact (auth is the flat public + permissions pair, no name/request/response field) folded into Auth Configuration
API-C-01:472-510 Datasource Configuration + Supported Driversa defineDatasource example and a 7-row driver tabledeleted → one pointer: objectstack-data rules/datasources.md, objectstack-platform Driver Selection Guide, and data/driver/config-registry.zod.ts for the id vocabulary
API-C-02:513-538 Inter-Service CommunicationIDataEngine contract prose + a marked block whose declare const kernel fabricated the hostdeleted → the section's slot now carries the API-F-02 construct; service resolution points at objectstack-platform rules/service-registry.md
API-C-03:458-468 Security Layersa 4-row table naming no authorable key + a callout restating its own Description columndeleted → one boundary line under Authentication & Authorization
API-D-01 + API-F-05 + API-A-03:316-366 Service Discovery / Healtha ServiceInfoos:check example, a JSON health body, /ready proserewritten to 3 lines — all three are response surfaces, nothing to author
API-D-02:383-396 Handler Statusa 3-row table its own callout neutralised ("nothing reads it at runtime")deleted; the now-single-child ## Dispatcher & Routing wrapper collapses into ## Dispatcher Error Codes
API-B-01:419-429third rendering of "no nested auth block" + an unmarked duplicate fragmentdeleted, merged into one sentence that also carries the API-E-01 fold
API-B-02 + API-G-01:203-209a second objectstack validate gate block 384 lines from the firstdeleted — the gate is stated once, in Verify your work, in the bundle-dominant os spelling
API-B-03:65-71, :283-313, :559-563the apiMethods primitives/derived rule stated 3×once. Callout → 3 lines; derived table drops the 3 rows with no route and no derivation (history/restore/purge keep a one-line mention); Best Practice 6 stops restating it
API-B-05:22-28preamble restating the frontmatter above the folddeleted
API-A-01:31-39 "When to Use This Skill"6 bullets, 3 of which misrouteSkill Boundaries table, matching objectstack-data / objectstack-query
API-A-02frontmatter :3-12promises "batch/versioning contracts""batch contracts"versioning.zod.ts has zero consumers outside a pin test
API-A-03:83-94three /meta client query-param contracts2 lines saying they are client contracts nothing declares
API-D-03:544-547, :556-558Best Practices 1 and 4deleted (1 duplicates :273 and is wrong for the carve-out; 4 names no key and no gate)
API-D-04:569-576Pitfalls 1, 2, 4deleted — FLS has no authorable spelling in the bundle, the page sizes match no platform constant, rate limiting is already the D6 rule
API-D-05:191-198two why-paragraphs after the carve-out ruledeleted, rule kept
API-F-04 + API-G-03:275-279environment-scoped routes + projectResolution, 0 usagesdeleted (takes the retired project gloss with it)
API-F-06:404-411two declared-but-unenforced realtime notesdeleted from the skill; filed as #14446
API-G-02:481defineDatasource imported from the root barrelmoot — deleted with API-C-01
API-F-01(add)gap — :164 named http.server with no exampleone table cellnew ## Code routes: mounting on http.server` section
API-F-02(add)gap — :548-555frontmatter promised "error envelopes"; the ledger rule was absentnew ## Error Envelopes & the Code Ledger (ADR-0112)
API-F-03(add):575-576"use optimistic locking (version field)", naming no spellingthe two real spellings, body-wins, 409 CONCURRENT_UPDATE

The three funded additions — every claim, with its source

1. http.server code mount — verified against all three shipping sites (examples/app-showcase/src/system/server/recalc-endpoint.ts:48-118, packages/plugins/plugin-sharing/src/sharing-plugin.ts:787-790, packages/plugins/plugin-approvals/src/approvals-plugin.ts:353-356).

  • dual lookup readServer('http.server') ?? readServer('http-server'), canonical first — sharing-plugin.ts:787-790, approvals-plugin.ts:353-356; both carry the same comment that http.server is "the ONLY name present on all provider paths".
  • kernel:ready, not later — packages/spec/src/contracts/plugin-lifecycle-events.ts:70-91: listen() is deferred to kernel:listeningbecause "route registration in Hono … seals the matcher the first time a request is matched"; recalc-endpoint.ts:110-112 hooks kernel:ready.
  • the handler signature — RouteHandler = (req: IHttpRequest, res: IHttpResponse) at packages/spec/src/contracts/http-server.ts:108-111; IHttpResponse.status(code): IHttpResponse at :77 (so res.status(200).json(…) chains); IHttpServer.post at :216.
  • the block is NOT os:check-marked, deliberately. See "Assumption 3" below — this is measured, not assumed.

2. ADR-0112 error-code ledgerpackages/spec/src/api/error-code-ledger.zod.ts:6-56 states the two tiers, "An unregistered code fails schema parse — which fails the envelope conformance suites — which fails CI", the framework-packages-only scope rule (#4805, maintainer ruling 2026-08-03 re-confirmed 2026-08-09), and the downstream composition. Functions re-located by content on this base: makeApiErrorSchema at packages/spec/src/api/contract.zod.ts:146, envelopeViolations at :215.

3. OCCpackages/rest/src/rest-server.ts:7710-7727 is the PATCH /api/v1/data/:object/:id route: If-Match header or expectedVersion body field, const expectedVersion = bodyVersion ?? ifMatchHeader (body wins), and the field is stripped from the write payload. The token semantics, the 409 and the "" refusal are the spec's own .describe() at packages/spec/src/api/protocol.zod.ts:2097-2102. CONCURRENT_UPDATE is registered at packages/spec/src/api/error-code-ledger.zod.ts:168 and pinned to 409 at packages/rest/src/rest-unclassified-fault-status.test.ts:230.

premise_false

API-F-01, the "getService is async" clause — the audit's premise is false and was NOT written. The real host contract is PluginContext.getService[T](name: string): T (packages/core/src/types.ts:36, doc comment @throws Error if service not found) — synchronous, and it throws. Measured on this base:

  • await ctx.getService in packages/plugins/**, excluding tests: 0 occurrences.
  • non-awaited ctx.getService( / ctx.getService[T](, same scope: 112.
  • the three app sites are ctx?.getService?.('manifest') with no await (packages/apps/{account,setup,studio}/src/index.ts:{60,55,68}).

The audit's evidence for "async" was recalc-endpoint.ts:52, which awaits — but that file's ctx is its own locally declared RecalcHostContext (:30-35) whose getService?: (name) => Promise<T> is a shim, not the host. That is precisely the defect API-C-02 was deleted for, so the skill states the true rule instead: getService is synchronous and throws, which is exactly why each name needs its own try and a() ?? b() in one try never reaches b.

The :532 "fix or unmark" item needs neither — the block is deleted with API-C-02, so no marker survives to prove or disprove anything.

PM assumptions — all six measured

#assumptionverdict
1skills/objectstack-api/** byte-identical a59f78d ↔ baseHOLDSgit diff a59f78d 96b627d1 -- skills/objectstack-api/ is empty; every audited span matched by content
2the frontmatter edit forces regeneration of BOTH generated filesHOLDScheck:skill-docs red on both before gen:skill-docs, green after; the .mdx pulled 20 docs-family gates into the union, re-derived and run
3the real PluginContext is unreachable from the os:check skills surfaceHOLDS, measured directly.SURFACES[0] resolves resolutionDir/selfPackages = packages/spec only (packages/spec/scripts/check-skill-examples.ts:526-532). Probed it: a temporary marked block importing PluginContext from @objectstack/core fails TS2307: Cannot find module '@objectstack/core'. Probe reverted and proven byte-identical (worktree blob hash == HEAD blob hash, git diff HEAD empty). ⇒ the F-01 block stays unmarked rather than earning a marker with a fabricated stand-in
4RestApiEndpointSchema 0 consumers · no plugin-rest-api package · no endpoints keyHOLDS — 0 hits outside packages/spec/src/api/plugin-rest-api* (positive control: the same grep for ApiEndpoint returns many); ls packages/plugins/ | grep -i rest empty; RestApiPluginConfig (packages/rest/src/rest-api-plugin.ts:95-105) is exactly {serverServiceName?, protocolServiceName?, kernelManagerServiceName?, api?}
5a heading in this file may be bound by check:skill-identifier-liveness Leg 2YES, and it is. Binding api-methods binds ## API Methods (Operations) to ApiMethod (scripts/check-skill-identifier-liveness.mjs:285-292). Fixed the author's way: the heading and all six primitives stay; only the derived rows moved. Gate green, 9 bindings, 0 ledgered gaps
6a false premise is skipped and listedapplied to the getService clause above

Token delta

filebeforeafterΔceiling
skills/objectstack-api/SKILL.md63114635−1,676 (−26.6%)6319, unchanged (headroom 8 → 1684)
skills/objectstack-api/evals/README.md5465460546 — untouched, API-H-01 deferred
skills/objectstack-api/references/_index.md8888880generator-owned, untouched
bundle, ratcheted (authored)171406169730−1,676171743

607 → 428 lines. No ceiling raised, no new file, no file deleted, and scripts/check-skills-token-ratchet.mjs is not edited.

The gap, itemised rather than smoothed. The dispatch target was −1,725 to −2,100; this lands at −1,676, short by 49 tokens (2.8%). It is not spread thin — it is two opposing errors in the audit's own estimates:

  • the three funded additions cost 239 tokens more than funded: F-01 271 actual vs +130 budgeted; F-02 162 vs +120; F-03 +96 net vs +40. Each was trimmed once already (F-01 from 407 tokens, F-02 from 250); trimming further would start dropping the load-bearing clauses each was funded to carry.
  • the deletions cut about 190 tokens more than the audit's per-span estimates, which is what absorbs most of that.

Closing the last 49 would mean cutting content no finding covers. Deliberately not done.

follow-up for objectstack-data / objectstack-platform

Both anchors are stronger than what this PR deleted, on every axis but one. Verified by heading on origin/claude/issue-14297-skills-data-optimization and origin/claude/issue-14299-skills-platform-optimization (what will merge):

  • objectstack-data/rules/datasources.md — byte-identical to origin/main on the data flight's branch; headings ## schemaMode — who owns the schema, ## Auto-connect (no onEnable), ## Credentials — fail-closed, ## Writes — double opt-in. ✅
  • objectstack-platform/SKILL.md## Driver Selection Guide — carries driver packages, class names, and the Turso "Cloud / EE onlyUnsupportedDriverError" caveat that the deleted api table omitted. ✅ Also ## Well-Known Plugin Names & Services and rules/service-registry.md both present. ✅
  • the one gap: neither anchor names the driver id vocabulary an author actually writes in defineDatasource({ driver: … })postgres, mysql, mongodb, sqlite, sqlite-wasm, turso, memory, and the mongo alias. The deleted api table did. Nothing is lost here — the pointer names the authoritative source, packages/spec/src/data/driver/config-registry.zod.ts:163 (resolveDriverId handles the aliases) — but a row in objectstack-data/rules/datasources.md would be the right home. Not filed as a card: it is one row inside a flight already in review; raising it here so that flight's reviewer can take it.

One file outside the declared surface, and why

scripts/role-word-baseline.jsoncheck:role-word went red on this branch with its ratchet-DOWN remedy, because API-C-03 deleted the file's single baselined occurrence of the reserved word (the Security Layers row | **RBAC** | Object | Role-based access control (profile → permissions) |). The gate names --update as the author's own path when a baselined file goes clean; leaving the entry would leave budget a later edit could spend silently. Baseline 43 → 42 files; the skills/objectstack-api/SKILL.md row is dropped, no other row moves. Committed separately.

Out-of-scope card filed

#14446 — declared ≠ enforced (ADR-0049): RealtimeEventType (packages/spec/src/api/realtime.zod.ts:33-40) spells record.* while the platform emits data.record.* (api/events.zod.ts:139-141), and SubscriptionSchema.filters is z.unknown().optional() (realtime.zod.ts:49). finding label, unassigned, no pm-state, no priority. Dedupe searched first — the four nearest cards (#4602, #4626, #4673, #9055) are all closed and none covers this pair.

Gates — head sha 19ee5853

Union re-derived after regeneration and again after the final commit: node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands42 commands (the .mdx output pulled in the docs family; the role-word baseline added 6 more: check:bash32-floor, check:cli-command-ids, check:entry-guard, check:parse-guard, check:pnpm-filter-targets, check:watch-hint-literal). All 42 run at 19ee5853; every exit code captured before any pipe.

41 green, 1 NOT MEASURED, 0 red.

  • node scripts/check-skills-token-ratchet.mjs✓ … 38 authored bundle file(s) within their ceilings
  • pnpm --filter @objectstack/spec check:skill-examples✅ 255 prose examples type-check across 3 surface(s) — every marked block parsed, so tsc ran the SEMANTIC pass on all of them (run under the shared verify lock; os-verify-lock: VERDICT command-exit 0). @objectstack/spec, @objectstack/client-react and @objectstack/formula closures built first, also under the lock — VERDICT command-exit 0 — so this gate could refuse rather than false-green.
  • pnpm check:skill-identifier-livenessOK — Leg 1: 488 citation(s) over 48 published file(s) …; Leg 2: 9 registered exhaustive section(s), 0 ledgered gap(s) (baseline was 500 citations; the drop is the deleted tables)
  • pnpm check:skill-compatibility✓ … 11 SKILL.md file(s) reconciled against 78 workspace packages
  • pnpm --filter @objectstack/spec check:skill-docs✅ Skill docs in sync
  • pnpm check:role-word after the ratchet-down
  • node scripts/check-nul-bytes.mjsOK (scanned 7875 text file(s) … no raw ASCII control bytes), plus a direct control-byte grep over the three edited files: no hits
  • NOT MEASURED:node scripts/check-test-completeness.mjs exits 3, its own "PREREQUISITE NOT MET" code — it needs a saved turbo run test log this run has no reason to produce. Its own text: "Nothing was measured … It is NOT a finding". CI supplies the log.

Two gates were exit-3 / exit-1 prerequisite states on the first pass and turned green once the closures were built, not by any edit: check:doc-formula-expressions + check:doc-security-posture (needed @objectstack/formula built) and check:docs (needed gen:schema, which build runs first).

Labels

skip-changeset — nothing released by any package changes. Checked against scripts/check-empty-changeset.mjs's own enumeration (:357: "It releases nothing (.github/, .claude/, skills/, docs/, content/, examples/…)"); this diff is skills/** + content/docs/** + one scripts/ ledger. needs:contract-review on both this PR and the card — the OCC contract, the error-ledger rule and the http.server mount timing are contract-semantics claims.

Stays draft: governed face.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1


Generated by Claude Code

…Schema example; teach http.server mount, the ADR-0112 code ledger and OCC
Optimization flight over skills/objectstack-api/SKILL.md (audit record posted
on the card). Shrink-only, additions paid by deletions in the same file.
DELETE / MERGE / REWRITE
API-E-01 the leading os:check example taught RestApiEndpointSchema: 0
consumers repo-wide, no plugin-rest-api package, and
RestApiPluginConfig has no `endpoints` key. The one live fact
(auth is the flat public + permissions pair) folded into the
auth section.
API-C-01 datasources + driver table -> objectstack-data rules/datasources.md
and objectstack-platform "Driver Selection Guide" (both carry more
than this file did, including the Turso Cloud/EE caveat).
API-C-02 inter-service communication -> objectstack-platform
rules/service-registry.md. Removes the `declare const kernel`
block that type-checked against a fabricated host shape.
API-C-03 Security Layers table named no authorable key -> one boundary line.
API-D-01 health/readiness response bodies -> one line (F-05, A-03).
API-D-02 Handler Status table, neutralised by its own callout.
API-D-03 Best Practices 1 and 4 (duplicate / no key, no gate).
API-D-04 Pitfalls 1, 2, 4 (FLS has no authorable spelling; the page sizes
match no platform constant; rate limiting is stated at D6).
API-D-05 the carve-out why-prose; the rule stays.
API-B-01 third rendering of "no nested auth block".
API-B-02 second gate invocation (and the `objectstack validate` spelling,
API-G-01) -> Verify your work states it once.
API-B-03 the apiMethods primitives/derived rule, stated 3x -> once. The
`## API Methods (Operations)` heading and all six ApiMethod members
stay: it is a registered exhaustive section (binding `api-methods`
in scripts/check-skill-identifier-liveness.mjs).
API-B-05 preamble restating the frontmatter.
API-F-04 environment-scoped routes / projectResolution, 0 usages (G-03).
API-F-05 ServiceInfo, a response shape with 0 usages -> one line.
API-F-06 the two declared-but-unenforced realtime notes (filed separately).
API-A-01 "When to Use This Skill" -> Skill Boundaries table, matching the
objectstack-data / objectstack-query form.
API-A-02 frontmatter drops the "versioning" promise: versioning.zod.ts has
zero consumers outside a pin test.
API-A-03 the description forbids the client seat; the body taught it.
ADD (funded)
API-F-01 the http.server code-mount example, the only code-route pattern the
repo ships. Left UNMARKED: `ctx` is @objectstack/core's
PluginContext and the skills os:check surface resolves
@objectstack/spec only, so a marker would need a locally declared
stand-in -- the same thing API-C-02 was deleted for.
Measured correction to the audit: ctx.getService is SYNCHRONOUS and
throws (0 awaited call sites in packages/plugins, 112 sync).
API-F-02 the ADR-0112 two-tier error-code ledger and the downstream
envelopeViolations + makeApiErrorSchema composition.
API-F-03 OCC stated with its real spellings: If-Match header or
expectedVersion body field, body wins, 409 CONCURRENT_UPDATE.
6311 -> 4635 tokens (ceiling 6319, unchanged); 607 -> 429 lines.
Part of #14304
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
…matter edit
Generator output only: `pnpm --filter @objectstack/spec gen:skill-docs` writes
both files from the SKILL.md frontmatter, and `check:skill-docs` fails without
this. The only change is API-A-02 dropping "versioning" from the description.
Part of #14304
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
`check:role-word` red on this branch with the ratchet-DOWN remedy: the file's
one baselined occurrence of the reserved word was the Security Layers row
`| **RBAC** | Object | Role-based access control (profile -> permissions) |`,
deleted by API-C-03. The gate names `--update` as the author's own path when a
baselined file goes clean, so the entry is dropped rather than left as budget a
later edit could spend silently. Baseline 43 -> 42 files; the objectstack-api
row is gone, no other row moves.
Part of #14304
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
@os-zhuang
os-zhuang marked this pull request as ready for review September 2, 2026 08:26
@os-zhuang
os-zhuang added this pull request to the merge queueSep 2, 2026
Merged via the queue into main with commit bae4088Sep 2, 2026
44 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-14304-skills-api-optimization branch September 2, 2026 09:03
os-zhuang added a commit that referenced this pull request Sep 2, 2026
…e base (#13823)
The published skill taught handlerStatus at this PR's base; main dropped that
teaching in the #14448 optimization flight (bae4088), so the changeset —
release-notes input — no longer claims an outstanding skills limb.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GDA48PuRFrHyRfdkBz8m21
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/mskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@os-litant@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

skills(api): optimization flight — RestApiEndpointSchema example and other packages' anchors cut, the apiMethods rule stated once, http.server mount / error ledger / OCC taught (net −1,676 tokens) - #14448

Merged
os-zhuang merged 3 commits into
mainfrom
claude/issue-14304-skills-api-optimization
Sep 2, 2026
Merged

Conversation

@os-litant

Copy link
Copy Markdown
Collaborator

Part of #14304

The audit record this implements is posted verbatim on the card. Every claim written into the file was re-verified at source on this branch's base; the file:line for each is below. evals/README.md is untouched (API-H-01 is deferred to #14296 item 2), so the card stays open — that is why the first line is Part of, not a closing keyword.

Per-item: 落点 | before | after

finding落点 (before)beforeafter
API-E-01SKILL.md:117-146 — the leading os:check exampleauthored RestApiEndpointSchema "via the REST API plugin"deleted. The one live fact (auth is the flat public + permissions pair, no name/request/response field) folded into Auth Configuration
API-C-01:472-510 Datasource Configuration + Supported Driversa defineDatasource example and a 7-row driver tabledeleted → one pointer: objectstack-data rules/datasources.md, objectstack-platform Driver Selection Guide, and data/driver/config-registry.zod.ts for the id vocabulary
API-C-02:513-538 Inter-Service CommunicationIDataEngine contract prose + a marked block whose declare const kernel fabricated the hostdeleted → the section's slot now carries the API-F-02 construct; service resolution points at objectstack-platform rules/service-registry.md
API-C-03:458-468 Security Layersa 4-row table naming no authorable key + a callout restating its own Description columndeleted → one boundary line under Authentication & Authorization
API-D-01 + API-F-05 + API-A-03:316-366 Service Discovery / Healtha ServiceInfoos:check example, a JSON health body, /ready proserewritten to 3 lines — all three are response surfaces, nothing to author
API-D-02:383-396 Handler Statusa 3-row table its own callout neutralised ("nothing reads it at runtime")deleted; the now-single-child ## Dispatcher & Routing wrapper collapses into ## Dispatcher Error Codes
API-B-01:419-429third rendering of "no nested auth block" + an unmarked duplicate fragmentdeleted, merged into one sentence that also carries the API-E-01 fold
API-B-02 + API-G-01:203-209a second objectstack validate gate block 384 lines from the firstdeleted — the gate is stated once, in Verify your work, in the bundle-dominant os spelling
API-B-03:65-71, :283-313, :559-563the apiMethods primitives/derived rule stated 3×once. Callout → 3 lines; derived table drops the 3 rows with no route and no derivation (history/restore/purge keep a one-line mention); Best Practice 6 stops restating it
API-B-05:22-28preamble restating the frontmatter above the folddeleted
API-A-01:31-39 "When to Use This Skill"6 bullets, 3 of which misrouteSkill Boundaries table, matching objectstack-data / objectstack-query
API-A-02frontmatter :3-12promises "batch/versioning contracts""batch contracts"versioning.zod.ts has zero consumers outside a pin test
API-A-03:83-94three /meta client query-param contracts2 lines saying they are client contracts nothing declares
API-D-03:544-547, :556-558Best Practices 1 and 4deleted (1 duplicates :273 and is wrong for the carve-out; 4 names no key and no gate)
API-D-04:569-576Pitfalls 1, 2, 4deleted — FLS has no authorable spelling in the bundle, the page sizes match no platform constant, rate limiting is already the D6 rule
API-D-05:191-198two why-paragraphs after the carve-out ruledeleted, rule kept
API-F-04 + API-G-03:275-279environment-scoped routes + projectResolution, 0 usagesdeleted (takes the retired project gloss with it)
API-F-06:404-411two declared-but-unenforced realtime notesdeleted from the skill; filed as #14446
API-G-02:481defineDatasource imported from the root barrelmoot — deleted with API-C-01
API-F-01(add)gap — :164 named http.server with no exampleone table cellnew ## Code routes: mounting on http.server` section
API-F-02(add)gap — :548-555frontmatter promised "error envelopes"; the ledger rule was absentnew ## Error Envelopes & the Code Ledger (ADR-0112)
API-F-03(add):575-576"use optimistic locking (version field)", naming no spellingthe two real spellings, body-wins, 409 CONCURRENT_UPDATE

The three funded additions — every claim, with its source

1. http.server code mount — verified against all three shipping sites (examples/app-showcase/src/system/server/recalc-endpoint.ts:48-118, packages/plugins/plugin-sharing/src/sharing-plugin.ts:787-790, packages/plugins/plugin-approvals/src/approvals-plugin.ts:353-356).

  • dual lookup readServer('http.server') ?? readServer('http-server'), canonical first — sharing-plugin.ts:787-790, approvals-plugin.ts:353-356; both carry the same comment that http.server is "the ONLY name present on all provider paths".
  • kernel:ready, not later — packages/spec/src/contracts/plugin-lifecycle-events.ts:70-91: listen() is deferred to kernel:listeningbecause "route registration in Hono … seals the matcher the first time a request is matched"; recalc-endpoint.ts:110-112 hooks kernel:ready.
  • the handler signature — RouteHandler = (req: IHttpRequest, res: IHttpResponse) at packages/spec/src/contracts/http-server.ts:108-111; IHttpResponse.status(code): IHttpResponse at :77 (so res.status(200).json(…) chains); IHttpServer.post at :216.
  • the block is NOT os:check-marked, deliberately. See "Assumption 3" below — this is measured, not assumed.

2. ADR-0112 error-code ledgerpackages/spec/src/api/error-code-ledger.zod.ts:6-56 states the two tiers, "An unregistered code fails schema parse — which fails the envelope conformance suites — which fails CI", the framework-packages-only scope rule (#4805, maintainer ruling 2026-08-03 re-confirmed 2026-08-09), and the downstream composition. Functions re-located by content on this base: makeApiErrorSchema at packages/spec/src/api/contract.zod.ts:146, envelopeViolations at :215.

3. OCCpackages/rest/src/rest-server.ts:7710-7727 is the PATCH /api/v1/data/:object/:id route: If-Match header or expectedVersion body field, const expectedVersion = bodyVersion ?? ifMatchHeader (body wins), and the field is stripped from the write payload. The token semantics, the 409 and the "" refusal are the spec's own .describe() at packages/spec/src/api/protocol.zod.ts:2097-2102. CONCURRENT_UPDATE is registered at packages/spec/src/api/error-code-ledger.zod.ts:168 and pinned to 409 at packages/rest/src/rest-unclassified-fault-status.test.ts:230.

premise_false

API-F-01, the "getService is async" clause — the audit's premise is false and was NOT written. The real host contract is PluginContext.getService[T](name: string): T (packages/core/src/types.ts:36, doc comment @throws Error if service not found) — synchronous, and it throws. Measured on this base:

  • await ctx.getService in packages/plugins/**, excluding tests: 0 occurrences.
  • non-awaited ctx.getService( / ctx.getService[T](, same scope: 112.
  • the three app sites are ctx?.getService?.('manifest') with no await (packages/apps/{account,setup,studio}/src/index.ts:{60,55,68}).

The audit's evidence for "async" was recalc-endpoint.ts:52, which awaits — but that file's ctx is its own locally declared RecalcHostContext (:30-35) whose getService?: (name) => Promise<T> is a shim, not the host. That is precisely the defect API-C-02 was deleted for, so the skill states the true rule instead: getService is synchronous and throws, which is exactly why each name needs its own try and a() ?? b() in one try never reaches b.

The :532 "fix or unmark" item needs neither — the block is deleted with API-C-02, so no marker survives to prove or disprove anything.

PM assumptions — all six measured

#assumptionverdict
1skills/objectstack-api/** byte-identical a59f78d ↔ baseHOLDSgit diff a59f78d 96b627d1 -- skills/objectstack-api/ is empty; every audited span matched by content
2the frontmatter edit forces regeneration of BOTH generated filesHOLDScheck:skill-docs red on both before gen:skill-docs, green after; the .mdx pulled 20 docs-family gates into the union, re-derived and run
3the real PluginContext is unreachable from the os:check skills surfaceHOLDS, measured directly.SURFACES[0] resolves resolutionDir/selfPackages = packages/spec only (packages/spec/scripts/check-skill-examples.ts:526-532). Probed it: a temporary marked block importing PluginContext from @objectstack/core fails TS2307: Cannot find module '@objectstack/core'. Probe reverted and proven byte-identical (worktree blob hash == HEAD blob hash, git diff HEAD empty). ⇒ the F-01 block stays unmarked rather than earning a marker with a fabricated stand-in
4RestApiEndpointSchema 0 consumers · no plugin-rest-api package · no endpoints keyHOLDS — 0 hits outside packages/spec/src/api/plugin-rest-api* (positive control: the same grep for ApiEndpoint returns many); ls packages/plugins/ | grep -i rest empty; RestApiPluginConfig (packages/rest/src/rest-api-plugin.ts:95-105) is exactly {serverServiceName?, protocolServiceName?, kernelManagerServiceName?, api?}
5a heading in this file may be bound by check:skill-identifier-liveness Leg 2YES, and it is. Binding api-methods binds ## API Methods (Operations) to ApiMethod (scripts/check-skill-identifier-liveness.mjs:285-292). Fixed the author's way: the heading and all six primitives stay; only the derived rows moved. Gate green, 9 bindings, 0 ledgered gaps
6a false premise is skipped and listedapplied to the getService clause above

Token delta

filebeforeafterΔceiling
skills/objectstack-api/SKILL.md63114635−1,676 (−26.6%)6319, unchanged (headroom 8 → 1684)
skills/objectstack-api/evals/README.md5465460546 — untouched, API-H-01 deferred
skills/objectstack-api/references/_index.md8888880generator-owned, untouched
bundle, ratcheted (authored)171406169730−1,676171743

607 → 428 lines. No ceiling raised, no new file, no file deleted, and scripts/check-skills-token-ratchet.mjs is not edited.

The gap, itemised rather than smoothed. The dispatch target was −1,725 to −2,100; this lands at −1,676, short by 49 tokens (2.8%). It is not spread thin — it is two opposing errors in the audit's own estimates:

  • the three funded additions cost 239 tokens more than funded: F-01 271 actual vs +130 budgeted; F-02 162 vs +120; F-03 +96 net vs +40. Each was trimmed once already (F-01 from 407 tokens, F-02 from 250); trimming further would start dropping the load-bearing clauses each was funded to carry.
  • the deletions cut about 190 tokens more than the audit's per-span estimates, which is what absorbs most of that.

Closing the last 49 would mean cutting content no finding covers. Deliberately not done.

follow-up for objectstack-data / objectstack-platform

Both anchors are stronger than what this PR deleted, on every axis but one. Verified by heading on origin/claude/issue-14297-skills-data-optimization and origin/claude/issue-14299-skills-platform-optimization (what will merge):

  • objectstack-data/rules/datasources.md — byte-identical to origin/main on the data flight's branch; headings ## schemaMode — who owns the schema, ## Auto-connect (no onEnable), ## Credentials — fail-closed, ## Writes — double opt-in. ✅
  • objectstack-platform/SKILL.md## Driver Selection Guide — carries driver packages, class names, and the Turso "Cloud / EE onlyUnsupportedDriverError" caveat that the deleted api table omitted. ✅ Also ## Well-Known Plugin Names & Services and rules/service-registry.md both present. ✅
  • the one gap: neither anchor names the driver id vocabulary an author actually writes in defineDatasource({ driver: … })postgres, mysql, mongodb, sqlite, sqlite-wasm, turso, memory, and the mongo alias. The deleted api table did. Nothing is lost here — the pointer names the authoritative source, packages/spec/src/data/driver/config-registry.zod.ts:163 (resolveDriverId handles the aliases) — but a row in objectstack-data/rules/datasources.md would be the right home. Not filed as a card: it is one row inside a flight already in review; raising it here so that flight's reviewer can take it.

One file outside the declared surface, and why

scripts/role-word-baseline.jsoncheck:role-word went red on this branch with its ratchet-DOWN remedy, because API-C-03 deleted the file's single baselined occurrence of the reserved word (the Security Layers row | **RBAC** | Object | Role-based access control (profile → permissions) |). The gate names --update as the author's own path when a baselined file goes clean; leaving the entry would leave budget a later edit could spend silently. Baseline 43 → 42 files; the skills/objectstack-api/SKILL.md row is dropped, no other row moves. Committed separately.

Out-of-scope card filed

#14446 — declared ≠ enforced (ADR-0049): RealtimeEventType (packages/spec/src/api/realtime.zod.ts:33-40) spells record.* while the platform emits data.record.* (api/events.zod.ts:139-141), and SubscriptionSchema.filters is z.unknown().optional() (realtime.zod.ts:49). finding label, unassigned, no pm-state, no priority. Dedupe searched first — the four nearest cards (#4602, #4626, #4673, #9055) are all closed and none covers this pair.

Gates — head sha 19ee5853

Union re-derived after regeneration and again after the final commit: node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands42 commands (the .mdx output pulled in the docs family; the role-word baseline added 6 more: check:bash32-floor, check:cli-command-ids, check:entry-guard, check:parse-guard, check:pnpm-filter-targets, check:watch-hint-literal). All 42 run at 19ee5853; every exit code captured before any pipe.

41 green, 1 NOT MEASURED, 0 red.

  • node scripts/check-skills-token-ratchet.mjs✓ … 38 authored bundle file(s) within their ceilings
  • pnpm --filter @objectstack/spec check:skill-examples✅ 255 prose examples type-check across 3 surface(s) — every marked block parsed, so tsc ran the SEMANTIC pass on all of them (run under the shared verify lock; os-verify-lock: VERDICT command-exit 0). @objectstack/spec, @objectstack/client-react and @objectstack/formula closures built first, also under the lock — VERDICT command-exit 0 — so this gate could refuse rather than false-green.
  • pnpm check:skill-identifier-livenessOK — Leg 1: 488 citation(s) over 48 published file(s) …; Leg 2: 9 registered exhaustive section(s), 0 ledgered gap(s) (baseline was 500 citations; the drop is the deleted tables)
  • pnpm check:skill-compatibility✓ … 11 SKILL.md file(s) reconciled against 78 workspace packages
  • pnpm --filter @objectstack/spec check:skill-docs✅ Skill docs in sync
  • pnpm check:role-word after the ratchet-down
  • node scripts/check-nul-bytes.mjsOK (scanned 7875 text file(s) … no raw ASCII control bytes), plus a direct control-byte grep over the three edited files: no hits
  • NOT MEASURED:node scripts/check-test-completeness.mjs exits 3, its own "PREREQUISITE NOT MET" code — it needs a saved turbo run test log this run has no reason to produce. Its own text: "Nothing was measured … It is NOT a finding". CI supplies the log.

Two gates were exit-3 / exit-1 prerequisite states on the first pass and turned green once the closures were built, not by any edit: check:doc-formula-expressions + check:doc-security-posture (needed @objectstack/formula built) and check:docs (needed gen:schema, which build runs first).

Labels

skip-changeset — nothing released by any package changes. Checked against scripts/check-empty-changeset.mjs's own enumeration (:357: "It releases nothing (.github/, .claude/, skills/, docs/, content/, examples/…)"); this diff is skills/** + content/docs/** + one scripts/ ledger. needs:contract-review on both this PR and the card — the OCC contract, the error-ledger rule and the http.server mount timing are contract-semantics claims.

Stays draft: governed face.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1


Generated by Claude Code

…Schema example; teach http.server mount, the ADR-0112 code ledger and OCC
Optimization flight over skills/objectstack-api/SKILL.md (audit record posted
on the card). Shrink-only, additions paid by deletions in the same file.
DELETE / MERGE / REWRITE
API-E-01 the leading os:check example taught RestApiEndpointSchema: 0
consumers repo-wide, no plugin-rest-api package, and
RestApiPluginConfig has no `endpoints` key. The one live fact
(auth is the flat public + permissions pair) folded into the
auth section.
API-C-01 datasources + driver table -> objectstack-data rules/datasources.md
and objectstack-platform "Driver Selection Guide" (both carry more
than this file did, including the Turso Cloud/EE caveat).
API-C-02 inter-service communication -> objectstack-platform
rules/service-registry.md. Removes the `declare const kernel`
block that type-checked against a fabricated host shape.
API-C-03 Security Layers table named no authorable key -> one boundary line.
API-D-01 health/readiness response bodies -> one line (F-05, A-03).
API-D-02 Handler Status table, neutralised by its own callout.
API-D-03 Best Practices 1 and 4 (duplicate / no key, no gate).
API-D-04 Pitfalls 1, 2, 4 (FLS has no authorable spelling; the page sizes
match no platform constant; rate limiting is stated at D6).
API-D-05 the carve-out why-prose; the rule stays.
API-B-01 third rendering of "no nested auth block".
API-B-02 second gate invocation (and the `objectstack validate` spelling,
API-G-01) -> Verify your work states it once.
API-B-03 the apiMethods primitives/derived rule, stated 3x -> once. The
`## API Methods (Operations)` heading and all six ApiMethod members
stay: it is a registered exhaustive section (binding `api-methods`
in scripts/check-skill-identifier-liveness.mjs).
API-B-05 preamble restating the frontmatter.
API-F-04 environment-scoped routes / projectResolution, 0 usages (G-03).
API-F-05 ServiceInfo, a response shape with 0 usages -> one line.
API-F-06 the two declared-but-unenforced realtime notes (filed separately).
API-A-01 "When to Use This Skill" -> Skill Boundaries table, matching the
objectstack-data / objectstack-query form.
API-A-02 frontmatter drops the "versioning" promise: versioning.zod.ts has
zero consumers outside a pin test.
API-A-03 the description forbids the client seat; the body taught it.
ADD (funded)
API-F-01 the http.server code-mount example, the only code-route pattern the
repo ships. Left UNMARKED: `ctx` is @objectstack/core's
PluginContext and the skills os:check surface resolves
@objectstack/spec only, so a marker would need a locally declared
stand-in -- the same thing API-C-02 was deleted for.
Measured correction to the audit: ctx.getService is SYNCHRONOUS and
throws (0 awaited call sites in packages/plugins, 112 sync).
API-F-02 the ADR-0112 two-tier error-code ledger and the downstream
envelopeViolations + makeApiErrorSchema composition.
API-F-03 OCC stated with its real spellings: If-Match header or
expectedVersion body field, body wins, 409 CONCURRENT_UPDATE.
6311 -> 4635 tokens (ceiling 6319, unchanged); 607 -> 429 lines.
Part of #14304
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
…matter edit
Generator output only: `pnpm --filter @objectstack/spec gen:skill-docs` writes
both files from the SKILL.md frontmatter, and `check:skill-docs` fails without
this. The only change is API-A-02 dropping "versioning" from the description.
Part of #14304
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
`check:role-word` red on this branch with the ratchet-DOWN remedy: the file's
one baselined occurrence of the reserved word was the Security Layers row
`| **RBAC** | Object | Role-based access control (profile -> permissions) |`,
deleted by API-C-03. The gate names `--update` as the author's own path when a
baselined file goes clean, so the entry is dropped rather than left as budget a
later edit could spend silently. Baseline 43 -> 42 files; the objectstack-api
row is gone, no other row moves.
Part of #14304
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
@os-zhuang
os-zhuang marked this pull request as ready for review September 2, 2026 08:26
@os-zhuang
os-zhuang added this pull request to the merge queueSep 2, 2026
Merged via the queue into main with commit bae4088Sep 2, 2026
44 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-14304-skills-api-optimization branch September 2, 2026 09:03
os-zhuang added a commit that referenced this pull request Sep 2, 2026
…e base (#13823)
The published skill taught handlerStatus at this PR's base; main dropped that
teaching in the #14448 optimization flight (bae4088), so the changeset —
release-notes input — no longer claims an outstanding skills limb.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GDA48PuRFrHyRfdkBz8m21
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/mskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@os-litant@os-zhuang@claude