Repository navigation
docs(skills): name the complete public-form opt-in the anonymous form endpoints read - #21650
Conversation
… endpoints read
The objectstack-api public-form section and the objectstack-ui assembly row named
two of the three `sharing` keys the anonymous form endpoints require. Both now
name `enabled: true` (schema default `false`), `allowAnonymous: true` and a
`publicLink` slug, the `404 FORM_NOT_FOUND` answer when any one is missing, and
the walled-posture condition with its `tenancy: { enabled: false }` remedy.
Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CB6W87z22K2yjUCDyVrJRk
Contract reviewServed-tier: Read-only shape: the diff against the merge base 15fe567, card #21567 with every comment, and this head's check-runs; nothing built or run locally. Reviewed by the dispatch seat in seat (served tier equals the constant's value, read from ① Derived judgments
② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS |
维护者速读(终稿)— PR #21650(#21567)· skills seat 1 · 2026-10-04T00:27Z改了什么: 两份对外发布的技能页里描述「匿名公开表单」开关的句子。 为什么改: 运行时规则已在 PR #21566 落到 风险与代价(含回滚): 纯技能文本,不碰 席位意见: 建议批准。每一句都对照 你要做的(一个动作): 在 PR #21650 上给一次 APPROVED review;批准后由席位清标、ready、挂 auto-merge 入队。 |
Fixes #21567
Clause-②: no
What
The published
objectstack-apiskill's public-form section named two of the threesharingkeys the anonymous form endpoints read, and theobjectstack-uiskill's UI-assembly row repeated the omission. An AI following either authors a form that bothGET /api/v1/forms/:slugandPOST /api/v1/forms/:slug/submitanswer404 FORM_NOT_FOUND. Both now state the complete opt-in as the merged rule reads it, plus the walled-posture condition and its remedy.Skill text only (
skills/**, Tier H). Nothing underpackages/**is touched; the shipped migration prose inpackages/spec/src/migrations/**stays as written (triage ruling 5967394091, "Not here").The rule the text now describes (read on
origin/main15fe567)packages/spec/src/ui/sharing.zod.ts:95—enabled: z.boolean().default(false).describe('Enable public sharing');:102—allowAnonymous: z.boolean().optional().default(false).packages/metadata-core/src/anonymous-form-intake.ts:66-68— the three checks (s.enabled !== true,s.allowAnonymous !== true,publicLinka non-empty string);:57-59—publicFormSlugfolds/forms/x,forms/xandxinto one slug.packages/rest/src/rest-server.ts:10807and:10977— both doors answer404 FORM_NOT_FOUNDwheneverresolveFormBySlugreturns null, which it also does for a form the posture withholds (:10781-10789).packages/metadata-core/src/anonymous-form-intake.ts:212— a wall is in force only on a posturepostureEnforcesWalladmits (group/isolated);:223-225— the remedy text: declaretenancy: { enabled: false }on an object whose rows belong to no organization.packages/metadata-protocol/src/runtime-authoring-gate.ts:404—PUBLIC_FORM_INTAKE_UNAVAILABLE = 'public-form-intake-unavailable', awarningthe authoring gate raises for aviewwrite (save and publish).Every
skills/**site that describes the opt-inSweep at 15fe567:
git grep -n -ioverskills/forallowAnonymous,publicLink,anonymous form,public form,forms/:slug,Web-to-Lead,web-to-case,guest_portal,walled.skills/objectstack-api/SKILL.md:77-78— "AnyFormViewdeclared withsharing.allowAnonymous: trueand apublicLinkslug is auto-mounted at:"enableddefault, and the404 FORM_NOT_FOUNDanswer when one is missingskills/objectstack-api/SKILL.md:94— "withallowAnonymous/publicLink"enabled/allowAnonymous/publicLinkskills/objectstack-api/SKILL.md:85-94— the paragraph after the route blockpublic-form-intake-unavailablewarning on save and publish, and thetenancy: { enabled: false }remedyskills/objectstack-ui/SKILL.md:208— the UI-assembly table's public-form rowsharing: { enabled: true, allowAnonymous: true, publicLink: 'slug' }skills/objectstack-data/SKILL.md:188— "public forms" in the list of surfaces a field's conditional rule applies toskills/objectstack-data/references/_index.md:57,skills/objectstack-ui/references/_index.md:48sharing.zod.ts, no opt-in proseNo other hit;
guest_portalandWeb-to-Leadoccur only inside the edited section.Readings
skills/objectstack-api/SKILL.mdskills/objectstack-ui/SKILL.mdskills/*/SKILL.mdTokens are the ratchet's own convention,
ceil(bytes / 4); the gate's lines at 4adec02: "skills/objectstack-api/SKILL.md is 4758 tokens (ceiling 6319; headroom 1561)" and "skills/objectstack-ui/SKILL.md is 3854 tokens (ceiling 3856; headroom 2)". Theobjectstack-uirow paid for its three keys inside the same line: the label "Public / anonymous form" is now "Public form" (the cell still carriesallowAnonymous), and "/ Web-to-Case" and "Auto-exposed" are dropped (the API skill's section keeps "Web-to-Lead / Web-to-Case"). No other line of that file moved; the sibling card #21537 holds the subforms example at :72-85.origin/mainwas still 15fe567 when this PR was opened, so no merge was owed.Tests
All 24 gate families that
node scripts/pm/dispatch-gates.mjs --commandsderives for this diff were run locally at4adec025, each exit captured before any pipe.--ranreconciliation: "24 derived famil(ies) accounted for — 24 run, 0 NOT-MEASURED (a DERIVED zero — all 24 recorded an exit code and none of them is 3)". Verdict lines:node scripts/check-skills-token-ratchet.mjsexit 0 — "✓ check-skills-token-ratchet: 54 authored bundle file(s) within their ceilings; 10 generator-owned file(s) measured, not ratcheted.";--self-testexit 0 — "65 cases pass".node scripts/check-doc-route-spelling.mjs --advisoryexit 0 — "✓ route-spelling guard (advisory): population clean — every shape-matched literal spells its ledger row.";--self-testexit 0.pnpm check:skill-identifier-livenessexit 0 — "Leg 1: 457 citation(s) over 53 published file(s) checked against 118365 implementation word tokens (0 ledgered exemption(s)); Leg 2: 8 registered exhaustive section(s), 0 ledgered gap(s)."pnpm --filter @objectstack/spec run check:skill-docsexit 0 — "✅ Skill docs in sync" (afterpnpm --filter @objectstack/spec buildunder the verify lock,VERDICT command-exit 0).pnpm --filter @objectstack/lint run check:doc-formula-expressions— first run exit 3,PREREQUISITE NOT MET(@objectstack/formulaand@objectstack/lintnot built; "Nothing was measured"); afterturbo run build --filter=@objectstack/formula --filter=@objectstack/lintunder the lock, exit 0.pnpm check:corpus-claim-drift,check:doc-authoring,check:role-word,check:skill-compatibility,check:skill-frame-sync,check:nul-bytes,check:agent-test-spelling,check:cross-package-test-inputs,check:driver-memory-census,check:gitlink-declared,check:pm-governed-merges,check:refd-timer-probe,check:watch-hint-literal,node scripts/check-ci-filter-parity.mjs,node scripts/check-closing-keyword-parity.mjs(and--self-test),node scripts/check-comment-mask-corpus.mjs— all exit 0.grep -naPspelling from the agent rules): clean.Not run locally, CI owns them: the repo-wide
pnpm lint, the type-check lanes and the package test suites — no package source changed.维护者速读(草稿)
改了什么: 两份对外发布的技能页(
objectstack-api、objectstack-ui)里描述「匿名公开表单」开关的句子,原来只写了allowAnonymous: true和publicLink两个键。现在补齐第三个键enabled: true(schema 默认是false),写明三者缺一则两个匿名端点都答404 FORM_NOT_FOUND,并加一句:在group/isolated这类带租户墙的部署姿态下,目标对象若按组织列隔离,表单同样不对外提供,保存与发布时会收到public-form-intake-unavailable警告,补救是对不归属任何组织的对象声明tenancy: { enabled: false }。为什么改: 运行时规则已在 PR #21566 落地到
main:三个键齐全才服务。技能文本是 AI 写元数据的直接依据,按旧文本写出来的表单会被两个端点同时拒绝,而作者不知道为什么。本 PR 让文本与已合并的规则、与SharingConfigSchema的默认值完全一致。风险与代价(含回滚): 纯文本改动,不碰
packages/**,无 changeset(skip-changeset)。objectstack-ui/SKILL.md的 token 棘轮只剩 2 的余量,所以那一行用同一行内的删字付账(行标签「Public / anonymous form」改为「Public form」,去掉「/ Web-to-Case」与「Auto-exposed」);objectstack-api/SKILL.md净增 6 行,在 PM 给的 +6 预算内。回滚:revert 本 PR 即可,没有派生产物。席位意见:
你要做的: 这是 Tier H 受管面(
skills/**),需要你的 APPROVED review;批准后由席位落地。请顺带看一眼objectstack-ui那一行的措辞取舍是否接受(标签缩短、去掉 Web-to-Case)。Acceptance notes
examples/app-showcase/src/ui/views/inquiry.view.ts:10andexamples/app-showcase/src/data/objects/inquiry.object.ts:10, and the header comments ofpackages/qa/dogfood/test/showcase-public-form.dogfood.test.ts:5andshowcase-public-form-withdrawal.dogfood.test.ts:7, narrate the opt-in with the two-key wording; the example view itself declares all three keys (inquiry.view.ts:70-73), as doesexamples/app-crm/src/views/lead.view.ts:124-126.CHANGELOG.md:607carries the pre-rule wording — release-owned history, never edited in a code PR.content/docs/ui/forms.mdx:23and:234already namesharing.enabled: true+sharing.allowAnonymous: true+publicLink; nothing owed there./forms/x,forms/xandxare one slug) is not in the skill text — it did not fit the +6 line budget; both example apps spellpublicLink: '/forms/contact-us', which the UI row'spublicLink: 'slug'placeholder admits.objectstack-fleet[bot](set with-c user.nameon this one commit; the container default isClaude); the trailer pair is the model-free form the pre-push hook accepted.Generated by Claude Code