You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[finding] Five GraphQL residue sites in skills/** still teach a removed surface, and one is mirrored into ai/skills-reference.mdx #10846
Found while implementing #10832 (the /graphql endpoint contract in content/docs/api/).
Filed rather than fixed: the source of truth is skills/**, which is governed /
human-merge-only, so patching the consumer doc page alone would only make it disagree with
the skill it catalogs.
The residue
/graphql is not mounted — packages/runtime/src/http-dispatcher.ts:2026 is // /graphql removed — GraphQL is not in the product plan (#2462 follow-on), there is no createGraphQLDomain among the fifteen domains at http-dispatcher.ts:556-574 (0 hits
repo-wide in packages/*/src), and no handleGraphQL in the runtime. Five sites in the
shipped skills still describe it as live:
Site
Text
Why it is wrong
skills/objectstack-api/SKILL.md:19
tags: rest, graphql, endpoint, auth, realtime, server
The skill's own description one line above lists REST endpoints, auth providers, realtime channels, error envelopes, batch/versioning contracts — no GraphQL. The tag contradicts the body.
There is no automatic GraphQL API. apiEnabled exposes REST (and MCP).
skills/objectstack-platform/SKILL.md:395
Mount explicit routes for auth, GraphQL, storage, discovery
/graphql is not mounted at all. (/storage in the same line is also stale — per http-dispatcher.ts:556-574's comment the two-route storage bridge was retired in #4087 and service-storage mounts its own surface.)
skills/objectstack-formula/SKILL.md:428
| `GraphQL.ComputedField` | `expression` | cel |
Listed as a CEL expression host. No such surface exists.
skills/objectstack-formula/SKILL.md:479
| `api/graphql` | cache key |
Same — names a api/graphql coordinate that has no module.
The mirror
content/docs/ai/skills-reference.mdx:156 reproduces the first row verbatim
(**Tags:** rest, graphql, endpoint, auth, realtime, server``). That page is
hand-written and is a catalog of the skills, so it should be corrected in the same change
as skills/objectstack-api/SKILL.md:19 — not before it, or the catalog and the skill drift
apart in the other direction.
Why this is worth a card
These files are the ones AI assistants load to learn the platform. A tag and a property table
that name a surface the runtime removed is exactly the input that generates client code
against a route which 404s — the same failure mode #10710 and #10832 fixed on the human-facing
docs, but aimed at the generated-code path instead of the reader.
Note skills/** is scanned by check:role-word (its own output reports skills 36 files), so
the corpus is already in a gate's population — it is reachable, just not checked for this.
Not in scope: skills/objectstack-formula/SKILL.md rows that name GraphQL as a general
industry concept, if any reviewer finds them; the five above all assert an ObjectStack surface.
Triage: routed domain:skills + finding + documentation, type Task. The five sites live in skills/** (published skills — governed, human-merge-only) and the skills lane self-triages its findings, so no grading here. Two notes for that seat: ① the mirror row in content/docs/ai/skills-reference.mdx:156 must move in the same change as skills/objectstack-api/SKILL.md:19 per the body's drift argument; ② published-skills PRs carry the whole-package value-density review question and the net-line budget discipline.
First-touch grading, concentrated round (skills seat, session session_01MsbKEG4LtERSLaDrbehM3e): finding → pm:queue. The published skills/** catalog is the platform's highest-value external face (maintainer 2026-08-21), and five sites teaching a removed surface are exactly the input that generates client code against a 404 — plus the /storage staleness noted in passing on the same line. The mirror (ai/skills-reference.mdx) corrects in the SAME change, per the card. Batch note: dispatches alongside the sharingModel-examples card (same catalog face) with a file-overlap check at dispatch; fold only if the surfaces intersect. Governed face — draft PR, human merge.
{
"issue": 10846,
"family": [10846, 10925],
"status": "needs_decision",
"branch": "claude/issue-10846-skills-catalog-pair",
"pr": "https://github.com/objectstack-ai/objectstack/pull/11141",
"premise_still_valid": true,
"premise_per_member": {
"10846": "VALID, all five sites plus the mirror still present and still wrong at the card's exact line numbers (no drift). Runtime re-verified at fix time: 0 hits for `createGraphQLDomain` under packages/*/src; `handleGraphQL` only in CHANGELOGs; http-dispatcher.ts:2069 carries the removal comment (card said :2026). The card's parenthetical about `/storage` on the platform line is ALSO correct and was verified before touching: adapters/hono/src/index.ts:423 is the `Storage: deliberately NOT mounted (#4087)` block, and the dispatcher carries the matching `No /storage domain (#4087)` note. Corrected in the same edit as instructed.",
"10925": "VALID, all four `ObjectSchema.create()` examples still omit `sharingModel`. Line numbers drifted as the card predicted: data 214/254/321 -> 214/254/323 after commit 1, upgrade 635 -> 635. None already fixed; no delta to report."
},
"commits": [
"b9c8009cd docs(skills): drop the five GraphQL residue sites and the stale /storage mount — Fixes #10846",
"e87585fa5 fix(skills): declare sharingModel on the 4 catalog examples, then scan skills/ for it — Fixes #10925"
],
"gates": {
"derived_how": "node scripts/pm/dispatch-gates.mjs with no hand-fed paths, at final commit e87585fa5 — 25 families matched, all run. Exit codes captured by redirect-then-capture, never after a pipe.",
"green_24": [
"check:doc-security-posture (the extended gate) — `26 ObjectSchema.create example(s) in 227 marked block(s) across 237 prose file(s) in 2 root(s) carry an os validate-clean security posture`; per-root census `docs 22 create site(s) in 191 marked block(s) across 189 .mdx file(s)` / `skills 4 create site(s) in 36 marked block(s) across 48 .md file(s)`. BORN GREEN, as the card required.",
"check:doc-authoring — `doc authoring guard: 389 files clean — no bare metadata literals.`",
"check:role-word — `Scanned: 225 .md/.mdx file(s) read across 2 root(s) — content/docs 189, skills 36.` (skills corpus in population, no new occurrences)",
"check:skill-compatibility — `11 SKILL.md file(s) reconciled against 78 workspace packages`",
"check:skill-frame-sync — `4 copies of the decision frame are structurally isomorphic across 3 files`",
"check:nul-bytes — `OK (scanned 6447 text file(s) ...; no raw ASCII control bytes)`",
"check:doc-formula-expressions, doc-anchors, doc-frontmatter, docs-audit-scope, docs-redirects, published-readme-links, pm-governed-merges, cross-package-test-inputs, slot-lookup, test-source-alias, type-source-resolution, ci-filter-parity, plugin-teardown-shape, affected-docs, and the four spec-liveness-check families (check:liveness, check:empty-state, check:strictness-ledger, check:variant-docs) — all exit 0"
],
"red_1": "check:skills-token-ratchet — `skills/objectstack-data/SKILL.md is 13817 tokens; the ratchet ceiling is 13797 (over by 20).` and `skills/objectstack-upgrade/SKILL.md is 8335 tokens; the ratchet ceiling is 8325 (over by 10).` See open_questions[0]. Deterministic, not flaky.",
"changeset": "NONE OWED, verified not assumed: packages/lint `files` is [dist, README.md, CHANGELOG.md], no `bin`, dist-only `exports` — scripts/** ships to no consumer, and no package src/ is touched. Declared with the `skip-changeset` label. Read back on the PR: labels are [documentation, size/m, skip-changeset], so the label survived the bots' whole-set PUT. An empty-frontmatter changeset was NOT used — scripts/check-empty-changeset.mjs rejects newly-added ones outright."
},
"tests": "All at final commit e87585fa5. Dependency closure built first in the fresh worktree (`pnpm --workspace-concurrency=2 --filter '@objectstack/lint...' build`, under scripts/pm/os-verify-lock.sh — `VERDICT command-exit 0 · held the lock 141s`); the gate imports validateSecurityPosture from dist, so an unbuilt run failed loudly with ERR_MODULE_NOT_FOUND rather than reading stale output. Gate self-test green: `self-test: ... judges the skills root by its own extension AND marker (neither spelling crosses); and holds the exemption ledger to the self-invalidating discipline in both directions.` REVERSE-VERIFICATION of the extended gate, from the COMMITTED state: re-removed the support_case `sharingModel`, confirmed the mutation ON DISK first (occurrence count 3 -> 2, plus the three-line site read back showing the key absent, plus `git diff --stat` 1 deletion) — not inferred from the edit tool's exit code — then ran the gate: exit 1, `skills/objectstack-data/SKILL.md:323 object \"support_case\" [security-owd-unset]`. Predicted direction was RED and RED is what happened. RESTORE LEG, reported honestly: the trap ran `git checkout HEAD -- <relative path>` while cwd had moved into packages/lint, so it printed `error: pathspec ... did not match any file(s) known to git` AND THEN printed its own `RESTORED (trap)` line — a false success. Caught by re-reading `git status`, which still showed the file modified. Restored by hand, verified byte-identical (occurrence count back to 3, site reads back with the key, `git status` clean), and the gate re-run on the restored tree returned to the green census above. No mutation survived into any later measurement. No package unit tests exist for a scripts/ gate; the script's own self-test is its test surface and it was extended with a skills leg.",
"open_questions": [
{
"question": "MEMBER 2 CANNOT LAND AS-IS. check:skills-token-ratchet is shrink-only with `⛔ MAINTAINER-ONLY` on the other direction, and every ceiling in the catalog sat at EXACTLY ZERO headroom before this PR. The four `sharingModel` lines are required by a gating-tier security rule (SECURITY_OWD_UNSET, severity error) and cost 30 tokens across two files with nowhere to put them: objectstack-data +20, objectstack-upgrade +10. That is the irreducible minimum — I already dropped my own explanatory comment on the crm_lead line to get upgrade from +21 down to +10. The gate names exactly two remedies and both are maintainer-only. Note the per-file unit hides a real fact: the BUNDLE grows by only 3 tokens (117919 -> 117922), because commit 1's residue deletions pay back 27 of the 30 — they just land in the wrong files (formula -19, platform -6, api -2).",
"options": [
"A — Raise the two ceilings by exactly the measured deltas (data 13797 -> 13817, upgrade 8325 -> 8335), with the ruling quoted in the PR body as the gate's own text requires. Cost: 30 tokens on the bundle, of which 27 are already paid back elsewhere in the same PR. Precedent shape exists in the file (CEILING_BASIS already carries a second, PR-specific basis).",
"B — Name the text to DELETE from objectstack-data and objectstack-upgrade as payment (~120 bytes total). Keeps the ratchet's discipline literally intact, but the choice of what to cut from the platform's highest-value published surface is an editorial call outside both cards, so it needs to be the maintainer's pick, not mine.",
"C — Land commit 1 alone now and defer member 2. Commit 1 is clean, all-green and only SHRINKS the bundle (-27 tokens); it is the FIRST commit on the branch, so it splits trivially. Cost: #10925's security defect stays live in the published catalog, and the gate extension stays deferred with it (extending the roots without the fixes makes the gate born red — the exact trap #10618 avoided).",
"D — Exempt os:check-required schema keys from the token ratchet. NOT RECOMMENDED and listed only to be dismissed: it makes the ratchet's unit negotiable per-author, which is precisely the control the 2026-08-21 ruling exists to remove."
],
"recommendation": "A, then C as the fallback if the ruling takes time. On real business need: these four lines are not a speculative surface — os validate rejects the copied app today, and the skills catalog is copied verbatim by AI authors, so the cost is paid per reader. On long-term soundness: A keeps ONE opinion about catalog length (the ratchet) and settles this instance by the mechanism the gate itself prescribes, rather than teaching authors that a security fix can be argued out of the budget. On making AI-authored metadata hard to get wrong: this IS that axis — an example that omits the OWD baseline is the leave_request incident's shape reproduced at catalog scale, and the extended gate closes the class permanently. On startup scope discipline: the ask is 30 tokens against a 117,919-token bundle (0.025%), net 3 after commit 1's paybacks, with no prose expansion whatsoever — every added byte is a required schema key. I did NOT self-fund by deleting catalog prose and did NOT touch a ceiling; both are explicitly the maintainer's call and either would have been an unreviewable change to a governed surface."
},
{
"question": "Value judgment on ONE of the four values, flagged rather than decided (it does not block). The card's fix shape says mirror a real example-app counterpart where one exists. `crm_lead` is the one exact name match — examples/app-crm/src/objects/lead.object.ts is `name: 'crm_lead'` with `sharingModel: 'public_read_write'` — so I mirrored it. But that value carries an explicit ADR-0090 D1 comment calling it a grandfather stamp: `record isolation for this demo object is intentionally org-shared`. Mirroring therefore teaches public_read_write in the published upgrade skill.",
"options": [
"A — Keep the mirror (`public_read_write`). Skill and example app agree about one object name; a reader diffing them finds no contradiction.",
"B — Use `'private'` for crm_lead too, consistent with the other three, and accept that the skill's crm_lead differs from app-crm's."
],
"recommendation": "A as landed, but genuinely close and a reviewer should confirm. A is what the card's own fix shape prescribes and avoids drift between the catalog and the app a reader is pointed at. The case for B is that a demo's grandfather stamp is not a value worth teaching, and the three data-skill objects took `'private'` for exactly that reason — I only diverged for crm_lead because the object NAME matches exactly, which the showcase counterparts do not (`showcase_account` / `showcase_invoice` are differently-named objects, so they are not counterparts and were defaulted)."
}
],
"out_of_scope_findings": [
"filed as #11140: two GraphQL residue sites in package SOURCE comments — packages/spec/src/data/object.zod.ts:252 (`Enable REST/GraphQL API access` on apiEnabled; its own .describe() one line below is already correct) and packages/adapters/hono/src/index.ts:105-106 (createHonoApp's JSDoc still names a `GraphQL raw result` route). Same defect class as this card one surface further in; the hono JSDoc is the likely ORIGIN of the stale platform-skill line this PR fixes, `/storage` included. Not folded in: different surface, different gate family, and a governed skills PR is the wrong place for it. Unassigned, `finding` label, no pm:queue. Dedup: search_issues on two phrasings returned only CLOSED cards (#10835, #10710, #10832, #10583, #7707, #9436, #4117), none covering either site."
],
"deviations": [
"Both members are committed on ONE branch/PR as dispatched, even though member 2's gate is red. Rationale: the claim comment already records this PR family as expected to sit unmerged behind the Console Pin Gate, so a second known-red gate with an explicit decision attached blocks nothing that was not already blocked — and it puts the complete, verified change in front of the decision-maker. Member 1 is the FIRST commit and is independently clean, so option C above is a trivial split.",
"The `skills/**` net-line budget was NOT self-raised and catalog prose was NOT self-deleted to fund the fix; the shortfall is reported instead (open_questions[0]).",
"PR body reports both required readings: per-file whole-file before/after and whole-package before/after, in lines AND in the ratchet's own token convention."
],
"summary": "Member 1 (#10846) is DONE and clean: all five GraphQL residue sites fixed in each file's own idiom, the `/storage` staleness on the platform line verified against http-dispatcher.ts and adapters/hono and corrected in the same edit as instructed, the two formula rows DELETED rather than replaced because nothing real fills either slot (no cache-key template surface exists at all), and the ai/skills-reference.mdx mirror moved in the SAME commit. skills/** now has zero GraphQL hits, and the commit SHRINKS the published bundle by 27 tokens. Member 2 (#10925) is implemented and verified but BLOCKED on a maintainer decision: the four sharingModel declarations are correct and the check-doc-security-posture skills/ root extension is born green with a passing reverse-verification, but the four required lines push check:skills-token-ratchet over on two files that had zero headroom, and both remedies the gate names are marked MAINTAINER-ONLY. Reporting the gap rather than self-funding it. One out-of-scope finding filed (#11140).",
"cleanup": "Worktree /home/user/objectstack-issue-10846 retained pending the decision above (removing it now would discard the branch checkout the follow-up patch round needs); no dev servers or background processes were started, nothing to tear down."
}
Correction to one line of the report above (not a second report — the os-dev-report comment stands as the record).
The cleanup field says the worktree was retained pending the decision. On reflection that was the wrong call: cleanup is an unconditional step of the task, and holding disk in a shared container against a decision that may take a while is not mine to trade. /home/user/objectstack-issue-10846 has been removed — rm -rf <path>/node_modules then git worktree remove with NO --force, which is itself the proof nothing uncommitted was left behind. Both commits are pushed to claude/issue-10846-skills-catalog-pair, so a follow-up patch round re-creates a worktree from the branch in about a minute and loses nothing.
Activity
huangyiirene commentedon Aug 21, 2026
Triage: routed
domain:skills+finding+documentation, type Task. The five sites live inskills/**(published skills — governed, human-merge-only) and the skills lane self-triages its findings, so no grading here. Two notes for that seat: ① the mirror row incontent/docs/ai/skills-reference.mdx:156must move in the same change asskills/objectstack-api/SKILL.md:19per the body's drift argument; ② published-skills PRs carry the whole-package value-density review question and the net-line budget discipline.Generated by Claude Code
os-zhuang commentedon Aug 22, 2026
First-touch grading, concentrated round (skills seat, session
session_01MsbKEG4LtERSLaDrbehM3e):finding→pm:queue. The publishedskills/**catalog is the platform's highest-value external face (maintainer 2026-08-21), and five sites teaching a removed surface are exactly the input that generates client code against a 404 — plus the/storagestaleness noted in passing on the same line. The mirror (ai/skills-reference.mdx) corrects in the SAME change, per the card. Batch note: dispatches alongside the sharingModel-examples card (same catalog face) with a file-overlap check at dispatch; fold only if the surfaces intersect. Governed face — draft PR, human merge.Generated by Claude Code
os-zhuang commentedon Aug 22, 2026
Claim: session_01MsbKEG4LtERSLaDrbehM3e branch=claude/issue-10846-skills-catalog-pair
skills 车道执行席认领——对子派发锚点(成员:本卡 + #10925,对外 skills catalog 面)。派发时文件重叠核查完毕:两卡同触⚠️ 落地提示同 #11126/#11129/#11137:入队将撞 Console Pin Gate 确定性红,与三单一起等 pin 链修复后统一处理。
skills/objectstack-data/SKILL.md⇒ 按定级预案合并为一次派发一个 PR,一员一提交各带 Fixes。范围:本卡五处 GraphQL 残留 + 镜像页content/docs/ai/skills-reference.mdx:156同笔更正;#10925 四处sharingModel缺失(修法钉在已合并的 #10714 扫掠先例)+ 修毕后扩check-doc-security-posture.mjs根到 skills/(先修后扩的时序即该卡自述的防「门生而红」陷阱)。治理面(skills/**命中即整 PR 治理):draft PR + 人工合并。Generated by Claude Code
docs(skills): drop the five GraphQL residue sites and the stale /stor…
os-zhuang commentedon Aug 22, 2026
os-dev-report
{ "issue": 10846, "family": [10846, 10925], "status": "needs_decision", "branch": "claude/issue-10846-skills-catalog-pair", "pr": "https://github.com/objectstack-ai/objectstack/pull/11141", "premise_still_valid": true, "premise_per_member": { "10846": "VALID, all five sites plus the mirror still present and still wrong at the card's exact line numbers (no drift). Runtime re-verified at fix time: 0 hits for `createGraphQLDomain` under packages/*/src; `handleGraphQL` only in CHANGELOGs; http-dispatcher.ts:2069 carries the removal comment (card said :2026). The card's parenthetical about `/storage` on the platform line is ALSO correct and was verified before touching: adapters/hono/src/index.ts:423 is the `Storage: deliberately NOT mounted (#4087)` block, and the dispatcher carries the matching `No /storage domain (#4087)` note. Corrected in the same edit as instructed.", "10925": "VALID, all four `ObjectSchema.create()` examples still omit `sharingModel`. Line numbers drifted as the card predicted: data 214/254/321 -> 214/254/323 after commit 1, upgrade 635 -> 635. None already fixed; no delta to report." }, "commits": [ "b9c8009cd docs(skills): drop the five GraphQL residue sites and the stale /storage mount — Fixes #10846", "e87585fa5 fix(skills): declare sharingModel on the 4 catalog examples, then scan skills/ for it — Fixes #10925" ], "gates": { "derived_how": "node scripts/pm/dispatch-gates.mjs with no hand-fed paths, at final commit e87585fa5 — 25 families matched, all run. Exit codes captured by redirect-then-capture, never after a pipe.", "green_24": [ "check:doc-security-posture (the extended gate) — `26 ObjectSchema.create example(s) in 227 marked block(s) across 237 prose file(s) in 2 root(s) carry an os validate-clean security posture`; per-root census `docs 22 create site(s) in 191 marked block(s) across 189 .mdx file(s)` / `skills 4 create site(s) in 36 marked block(s) across 48 .md file(s)`. BORN GREEN, as the card required.", "check:doc-authoring — `doc authoring guard: 389 files clean — no bare metadata literals.`", "check:role-word — `Scanned: 225 .md/.mdx file(s) read across 2 root(s) — content/docs 189, skills 36.` (skills corpus in population, no new occurrences)", "check:skill-compatibility — `11 SKILL.md file(s) reconciled against 78 workspace packages`", "check:skill-frame-sync — `4 copies of the decision frame are structurally isomorphic across 3 files`", "check:nul-bytes — `OK (scanned 6447 text file(s) ...; no raw ASCII control bytes)`", "check:doc-formula-expressions, doc-anchors, doc-frontmatter, docs-audit-scope, docs-redirects, published-readme-links, pm-governed-merges, cross-package-test-inputs, slot-lookup, test-source-alias, type-source-resolution, ci-filter-parity, plugin-teardown-shape, affected-docs, and the four spec-liveness-check families (check:liveness, check:empty-state, check:strictness-ledger, check:variant-docs) — all exit 0" ], "red_1": "check:skills-token-ratchet — `skills/objectstack-data/SKILL.md is 13817 tokens; the ratchet ceiling is 13797 (over by 20).` and `skills/objectstack-upgrade/SKILL.md is 8335 tokens; the ratchet ceiling is 8325 (over by 10).` See open_questions[0]. Deterministic, not flaky.", "changeset": "NONE OWED, verified not assumed: packages/lint `files` is [dist, README.md, CHANGELOG.md], no `bin`, dist-only `exports` — scripts/** ships to no consumer, and no package src/ is touched. Declared with the `skip-changeset` label. Read back on the PR: labels are [documentation, size/m, skip-changeset], so the label survived the bots' whole-set PUT. An empty-frontmatter changeset was NOT used — scripts/check-empty-changeset.mjs rejects newly-added ones outright." }, "tests": "All at final commit e87585fa5. Dependency closure built first in the fresh worktree (`pnpm --workspace-concurrency=2 --filter '@objectstack/lint...' build`, under scripts/pm/os-verify-lock.sh — `VERDICT command-exit 0 · held the lock 141s`); the gate imports validateSecurityPosture from dist, so an unbuilt run failed loudly with ERR_MODULE_NOT_FOUND rather than reading stale output. Gate self-test green: `self-test: ... judges the skills root by its own extension AND marker (neither spelling crosses); and holds the exemption ledger to the self-invalidating discipline in both directions.` REVERSE-VERIFICATION of the extended gate, from the COMMITTED state: re-removed the support_case `sharingModel`, confirmed the mutation ON DISK first (occurrence count 3 -> 2, plus the three-line site read back showing the key absent, plus `git diff --stat` 1 deletion) — not inferred from the edit tool's exit code — then ran the gate: exit 1, `skills/objectstack-data/SKILL.md:323 object \"support_case\" [security-owd-unset]`. Predicted direction was RED and RED is what happened. RESTORE LEG, reported honestly: the trap ran `git checkout HEAD -- <relative path>` while cwd had moved into packages/lint, so it printed `error: pathspec ... did not match any file(s) known to git` AND THEN printed its own `RESTORED (trap)` line — a false success. Caught by re-reading `git status`, which still showed the file modified. Restored by hand, verified byte-identical (occurrence count back to 3, site reads back with the key, `git status` clean), and the gate re-run on the restored tree returned to the green census above. No mutation survived into any later measurement. No package unit tests exist for a scripts/ gate; the script's own self-test is its test surface and it was extended with a skills leg.", "open_questions": [ { "question": "MEMBER 2 CANNOT LAND AS-IS. check:skills-token-ratchet is shrink-only with `⛔ MAINTAINER-ONLY` on the other direction, and every ceiling in the catalog sat at EXACTLY ZERO headroom before this PR. The four `sharingModel` lines are required by a gating-tier security rule (SECURITY_OWD_UNSET, severity error) and cost 30 tokens across two files with nowhere to put them: objectstack-data +20, objectstack-upgrade +10. That is the irreducible minimum — I already dropped my own explanatory comment on the crm_lead line to get upgrade from +21 down to +10. The gate names exactly two remedies and both are maintainer-only. Note the per-file unit hides a real fact: the BUNDLE grows by only 3 tokens (117919 -> 117922), because commit 1's residue deletions pay back 27 of the 30 — they just land in the wrong files (formula -19, platform -6, api -2).", "options": [ "A — Raise the two ceilings by exactly the measured deltas (data 13797 -> 13817, upgrade 8325 -> 8335), with the ruling quoted in the PR body as the gate's own text requires. Cost: 30 tokens on the bundle, of which 27 are already paid back elsewhere in the same PR. Precedent shape exists in the file (CEILING_BASIS already carries a second, PR-specific basis).", "B — Name the text to DELETE from objectstack-data and objectstack-upgrade as payment (~120 bytes total). Keeps the ratchet's discipline literally intact, but the choice of what to cut from the platform's highest-value published surface is an editorial call outside both cards, so it needs to be the maintainer's pick, not mine.", "C — Land commit 1 alone now and defer member 2. Commit 1 is clean, all-green and only SHRINKS the bundle (-27 tokens); it is the FIRST commit on the branch, so it splits trivially. Cost: #10925's security defect stays live in the published catalog, and the gate extension stays deferred with it (extending the roots without the fixes makes the gate born red — the exact trap #10618 avoided).", "D — Exempt os:check-required schema keys from the token ratchet. NOT RECOMMENDED and listed only to be dismissed: it makes the ratchet's unit negotiable per-author, which is precisely the control the 2026-08-21 ruling exists to remove." ], "recommendation": "A, then C as the fallback if the ruling takes time. On real business need: these four lines are not a speculative surface — os validate rejects the copied app today, and the skills catalog is copied verbatim by AI authors, so the cost is paid per reader. On long-term soundness: A keeps ONE opinion about catalog length (the ratchet) and settles this instance by the mechanism the gate itself prescribes, rather than teaching authors that a security fix can be argued out of the budget. On making AI-authored metadata hard to get wrong: this IS that axis — an example that omits the OWD baseline is the leave_request incident's shape reproduced at catalog scale, and the extended gate closes the class permanently. On startup scope discipline: the ask is 30 tokens against a 117,919-token bundle (0.025%), net 3 after commit 1's paybacks, with no prose expansion whatsoever — every added byte is a required schema key. I did NOT self-fund by deleting catalog prose and did NOT touch a ceiling; both are explicitly the maintainer's call and either would have been an unreviewable change to a governed surface." }, { "question": "Value judgment on ONE of the four values, flagged rather than decided (it does not block). The card's fix shape says mirror a real example-app counterpart where one exists. `crm_lead` is the one exact name match — examples/app-crm/src/objects/lead.object.ts is `name: 'crm_lead'` with `sharingModel: 'public_read_write'` — so I mirrored it. But that value carries an explicit ADR-0090 D1 comment calling it a grandfather stamp: `record isolation for this demo object is intentionally org-shared`. Mirroring therefore teaches public_read_write in the published upgrade skill.", "options": [ "A — Keep the mirror (`public_read_write`). Skill and example app agree about one object name; a reader diffing them finds no contradiction.", "B — Use `'private'` for crm_lead too, consistent with the other three, and accept that the skill's crm_lead differs from app-crm's." ], "recommendation": "A as landed, but genuinely close and a reviewer should confirm. A is what the card's own fix shape prescribes and avoids drift between the catalog and the app a reader is pointed at. The case for B is that a demo's grandfather stamp is not a value worth teaching, and the three data-skill objects took `'private'` for exactly that reason — I only diverged for crm_lead because the object NAME matches exactly, which the showcase counterparts do not (`showcase_account` / `showcase_invoice` are differently-named objects, so they are not counterparts and were defaulted)." } ], "out_of_scope_findings": [ "filed as #11140: two GraphQL residue sites in package SOURCE comments — packages/spec/src/data/object.zod.ts:252 (`Enable REST/GraphQL API access` on apiEnabled; its own .describe() one line below is already correct) and packages/adapters/hono/src/index.ts:105-106 (createHonoApp's JSDoc still names a `GraphQL raw result` route). Same defect class as this card one surface further in; the hono JSDoc is the likely ORIGIN of the stale platform-skill line this PR fixes, `/storage` included. Not folded in: different surface, different gate family, and a governed skills PR is the wrong place for it. Unassigned, `finding` label, no pm:queue. Dedup: search_issues on two phrasings returned only CLOSED cards (#10835, #10710, #10832, #10583, #7707, #9436, #4117), none covering either site." ], "deviations": [ "Both members are committed on ONE branch/PR as dispatched, even though member 2's gate is red. Rationale: the claim comment already records this PR family as expected to sit unmerged behind the Console Pin Gate, so a second known-red gate with an explicit decision attached blocks nothing that was not already blocked — and it puts the complete, verified change in front of the decision-maker. Member 1 is the FIRST commit and is independently clean, so option C above is a trivial split.", "The `skills/**` net-line budget was NOT self-raised and catalog prose was NOT self-deleted to fund the fix; the shortfall is reported instead (open_questions[0]).", "PR body reports both required readings: per-file whole-file before/after and whole-package before/after, in lines AND in the ratchet's own token convention." ], "summary": "Member 1 (#10846) is DONE and clean: all five GraphQL residue sites fixed in each file's own idiom, the `/storage` staleness on the platform line verified against http-dispatcher.ts and adapters/hono and corrected in the same edit as instructed, the two formula rows DELETED rather than replaced because nothing real fills either slot (no cache-key template surface exists at all), and the ai/skills-reference.mdx mirror moved in the SAME commit. skills/** now has zero GraphQL hits, and the commit SHRINKS the published bundle by 27 tokens. Member 2 (#10925) is implemented and verified but BLOCKED on a maintainer decision: the four sharingModel declarations are correct and the check-doc-security-posture skills/ root extension is born green with a passing reverse-verification, but the four required lines push check:skills-token-ratchet over on two files that had zero headroom, and both remedies the gate names are marked MAINTAINER-ONLY. Reporting the gap rather than self-funding it. One out-of-scope finding filed (#11140).", "cleanup": "Worktree /home/user/objectstack-issue-10846 retained pending the decision above (removing it now would discard the branch checkout the follow-up patch round needs); no dev servers or background processes were started, nothing to tear down." }Generated by Claude Code
Generated by Claude Code
os-zhuang commentedon Aug 22, 2026
Correction to one line of the report above (not a second report — the
os-dev-reportcomment stands as the record).The
cleanupfield says the worktree was retained pending the decision. On reflection that was the wrong call: cleanup is an unconditional step of the task, and holding disk in a shared container against a decision that may take a while is not mine to trade./home/user/objectstack-issue-10846has been removed —rm -rf <path>/node_modulesthengit worktree removewith NO--force, which is itself the proof nothing uncommitted was left behind. Both commits are pushed toclaude/issue-10846-skills-catalog-pair, so a follow-up patch round re-creates a worktree from the branch in about a minute and loses nothing.Everything else in the report is unchanged.
Generated by Claude Code
Generated by Claude Code
docs(skills): clear the GraphQL residue from the published catalog an…