Skip to content

public forms: sharing.publicLink reads as the "Generated public share URL" but is only a slug — the authored path (/forms/contact-us) answers 404, and the real anonymous URL (/_console/f/<slug>) is shown to the author nowhere #22079

Closed

Description

@objectstack-fleet

Filing gate: ① product defect with reach measured. Class (a). reach: public door, an anonymous visitor opening the link an app declares for its public form. Measured on @objectstack/* 17.7.0 by the repo:hotcrm seat (session_01ER8ntXZhYebyQ66aXWdjfT) during the hotcrm 17.7.0 upgrade (hotcrm PR #2008), on the maintainer's word: 「4. 公开表单地址对不上 … 以上立卡」.

Who acts on it: objectstack triage routes it. ⛔ Not a claim.

Measured (17.7.0 boots of hotcrm's 17.7.0 upgrade branch, merged as c9678036; requests sent with no session)

hotcrm declares its Web-to-Lead form as sharing: { enabled: true, allowAnonymous: true, publicLink: '/forms/contact-us' } (src/sales/views/lead.view.ts:933). That is the same spelling the platform's own conversion fixtures use (packages/spec/src/conversions/registry.ts:14001, publicLink: '/forms/contact').

URL an author or visitor would try answer
GET /forms/contact-us (the path as authored) 404 {"success":false,"error":{"code":"ENDPOINT_NOT_FOUND","message":"Not found"}}
GET /_console/forms/contact-us redirect to /_console/login?redirect=%2Fforms%2Fcontact-us (the signed-in form route, keyed by form name)
GET /_console/f/contact-us ✅ the form, anonymously. A submission created its crm_lead

The working URL was found by trying paths. Nothing an author reads names it.

Code reading (origin/main 8caa131e52)

  • packages/spec/src/ui/sharing.zod.ts:96: publicLink: z.string().optional().describe('Generated public share URL').
  • packages/metadata-core/src/anonymous-form-intake.ts:62–64: publicFormSlug() strips a leading / and forms/. So /forms/x, forms/x and x are one slug: the value is a slug, not a URL, and nothing generates it.
  • The console serves the slug at /f/:slug (packages/spec/src/ui/view.zod.ts:3414, "The console's public form route (/f/:slug)").

Why it matters

  • An app author writes what the describe invites, a URL, and gets one that 404s for every visitor.
  • The link that has to go on a website (Contact us, Support) cannot be read from the metadata, from Studio, or from the docs the author is likely to open.

A direction, for triage to rule on (⛔ not a ruling)

  • Answer the authored path. Redirect GET /forms/<slug> (and the bare /<slug> spelling, if it is the declared one) to /_console/f/<slug>, but only when an enabled public form declares that slug. Or say plainly in the describe that the value is a slug, and give the URL it is served at.
  • Show the real anonymous URL wherever the form's sharing is edited or listed (Studio, the form view's share panel).
  • publicLink describing itself as "Generated" while every first-party example hand-writes it is a declared≠enforced wording question for the spec lane.

Duplicate check

Semantic issue search on objectstack, public form publicLink URL not served 404 ENDPOINT_NOT_FOUND console /f/ route: 1 hit, #12233 (closed, the docs site's soft-404), a different surface. Positive control: publicLink appears in the code readings above.

Dedupe words: publicLink 404 · public form URL · /f/:slug · ENDPOINT_NOT_FOUND forms · publicLink is a slug


Generated by Claude Code

Activity

  1. added
    pm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
    and removed on Oct 7, 2026
  2. objectstack-fleet commented on Oct 7, 2026

    @objectstack-fleet
    ContributorAuthor

    Path: ② the capabilities an end user meets in the app — public forms | 缺项 | P3

    Triage: pm:retriage answer: re-route domain:cli → domain:spec, re-graded p2 → p3. Only the publicLink describe remains

    Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-07T18:57Z. ⛔ Not a claim, ⛔ not a dispatch.

    This answers the release 6044120961. The redirect half landed (PR #22098 → dd39171835), so the visitor-facing 404 that made this p2 is gone.

    Triage: lands in packages/spec/src/ui/sharing.zod.ts:98 (publicLink: z.string().optional().describe('Generated public share URL'), read on main a543e244f0) ⇒ domain:spec; rationale: packages/spec always belongs to the spec seat (lanes/spec.md).

  3. added and removed
    domain:cliRetired 2026-10-22, alias of domain:server (cli surface); in-flight cards keep it until they land
    pm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
    on Oct 7, 2026
  4. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 (the publicLink describe half; the redirect half landed as PR #22098 → dd39171835) · 2026-10-08T02:43Z
    Session: session_01RPo7FUd6bSnAfkWMAKi848
    Account: os-justin (the seat's linked user as GET /user answers it; the card's assignee from this act)
    Branch: claude/issue-22079-publiclink-describe
    Worktree: objectstack-issue-22079
    Domain: domain:spec
    Seat: domain:spec#3 (seat post #18883)
    File surface (at origin/main ef1fcb26a2; stop on breach and explain in the report):

    • packages/spec/src/ui/sharing.zod.ts: the publicLink describe (:98, 'Generated public share URL').
    • The generated references it reaches (content/docs/references/**, merge=os-regen), any pin that asserts that describe, and .changeset/22079-*.md (patch, @objectstack/spec).
      Container & model: S, mode:subagent, model: opus (--tier: no path-derived mandate; describe text only; the path limb owes the contract review at CONTRACT_REVIEW_TIER on the landing head)
      Clause-②: no
      Responsibility: packages/spec's describe calls a slug a "generated public share URL" | the redirect half (PR feat(cli): the authored public form path /forms/:slug redirects to the console form page when the anonymous door serves it #22098) answers the authored /forms/<slug>, but nothing an author reads says the value is a slug or where it is served | every author of a public form in Studio, REST or MCP (measured on hotcrm's publicLink: '/forms/contact-us')
      Thread-read: 6044725872
      Serial constraints cleared: no open PR touches sharing.zod.ts or its generated reference (all open PRs' file lists read at this stamp). area:access in flight elsewhere: Design: does approver routing imply record read visibility? (#7345 model half) #7497 (a read-only design round in the services packages), a disjoint file surface.

    Clause-②: no per triage's re-grade 6044725872 (describe text only; the accept set does not change).

  5. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 22079,
    "status": "done",
    "branch": "claude/issue-22079-publiclink-describe",
    "pr": "#22159",
    "session": "session_01RPo7FUd6bSnAfkWMAKi848",
    "premise_still_valid": true,
    "summary": "The publicLink describe in packages/spec/src/ui/sharing.zod.ts:98 now says the value is an author-chosen slug, not a generated URL; that /forms/x, forms/x and x are one slug; that it is served only while enabled and allowAnonymous are both true; and where: the REST form door GET /api/v1/forms/:slug (default API base) on every host, and on a host that serves the console the page /_console/f/:slug with /forms/:slug redirected there, query carried. Route params are spelled :slug (the spelling view.zod.ts already uses) so nothing angle-bracketed reaches MDX or the GitHub sanitizer. The two generated references (content/docs/references/ui/sharing.mdx, ui/view.mdx) were regenerated with gen:docs after check:generated named them stale; no pin of the old text existed. Draft PR #22159, body line 1 'Fixes #22079', line 2 'Clause-②: no'; changeset .changeset/22079-publiclink-describe.md '@objectstack/spec': patch with 'Clause-②: no'. Card assignee untouched; PR assignee os-justin.",
    "describe_old": "Generated public share URL",
    "describe_new": "Public slug of the form, chosen by the author: not a URL, and never generated. /forms/x, forms/x and x name one slug, x. It is served to anonymous visitors only while enabled and allowAnonymous are both true: the REST form door answers GET /api/v1/forms/:slug (default API base), and a host that serves the console shows the form at /_console/f/:slug and redirects /forms/:slug there, query string carried.",
    "h1": "Holds at base ef1fcb2 (= PM read): sharing.zod.ts:98 publicLink: z.string().optional().describe('Generated public share URL'); publicFormSlug() at packages/spec/src/ui/anonymous-form-intake.ts:69-71 strips leading slashes then one 'forms/' prefix. SharingConfigSchema has one carrier, FormViewSchema.sharing (view.zod.ts:4386).",
    "h2": [
    "REST door: registerFormEndpoints registers GET {basePath}/forms/:slug (packages/rest/src/rest-server.ts:10842) and POST {basePath}/forms/:slug/submit (:11012), called for every base in registerForBase (:4519); default base = api.apiPath ?? basePath/version (getApiBasePath :4472-4475), /api/v1 by default, so the describe says '(default API base)'. The request slug is compared to the normalised candidate slug (c.slug !== slug, :10749).",
    "Console page: CONSOLE_PATH = '/_console' is a constant (packages/cli/src/utils/console.ts:54); the pinned console (.objectui-sha a58626c) routes /f/:slug to FormPage mode public (objectui apps/console/src/App.tsx:242, read at a58626c and at objectui main 9990f9e). The CLI mounts the console only with the ui tier on, flags.console true and OS_DISABLE_CONSOLE != '1' (packages/cli/src/commands/serve.ts:5035) and a resolved dist (createConsoleStaticPlugin at :5064). Hence 'a host that serves the console'.",
    "Redirect: GET /forms/:slug answers 302 to CONSOLE_PATH/f/encodeURIComponent(slug) plus new URL(c.req.url).search only when anonymousFormDoorServes (console.ts:865) gets a 200 from GET /api/v1/forms/SLUG in-process (console.ts:578-585); registered inside createConsoleStaticPlugin, so it exists exactly where the console does. Landed as PR #22098 (dd39171), an ancestor of the base.",
    "Sibling keys: anonymousFormIntakeSlug (anonymous-form-intake.ts:74-81) returns null unless enabled === true, allowAnonymous === true and publicLink is a non-empty string, so the describe says 'only while enabled and allowAnonymous are both true' (necessary, not sufficient: a layer withdrawal or the tenancy posture can still withhold the form).",
    "'Never generated': no objectstack code writes publicLink; objectui's Public Forms page saves '/forms/' + the slug the user typed (apps/console/src/pages/developer/PublicFormsPage.tsx:243, :314 at 9990f9e) and objectui core validateSharingConfig only refuses an enabled config without one."
    ],
    "h3": "git grep 'Generated public share URL' at base: 3 hits (sharing.zod.ts:98, content/docs/references/ui/sharing.mdx:58, content/docs/references/ui/view.mdx:489); no test pins it. At head: 1 hit, the changeset quoting the old text. Regenerated with the repo generator: check:generated at 8479c9a exit 1 ('1 of 15 artifact(s) stale: content/docs/references/'), gen:docs exit 0 (2 files, 1 line each), check:generated at 8d2e686 exit 0 ('All 15 generated artifacts are up to date').",
    "tests": "All at head 8d2e686 (git rev-parse --short HEAD) unless named. pnpm --filter @objectstack/spec build exit 0 at 8479c9a (the later commit touches only the two .mdx pages). pnpm --filter @objectstack/spec test: 'Test Files 623 passed (623)', 'Tests 18619 passed | 1 todo (18620)', exit 0. pnpm --filter @objectstack/spec typecheck exit 0 ('check:test-typecheck: OK'). Lint, narrowed and declared: pnpm exec eslint --no-inline-config --format json packages/spec/src/ui/sharing.zod.ts -> 1 file, 0 errors, 0 warnings; population read from eslint.config.mjs:971 ('
    /*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}', so the .md/.mdx paths are outside it); invariance: the config never enables type-aware linting (eslint.config.mjs:326-328), so the diff cannot move any untouched file's verdict; full pnpm lint left to CI. Control-byte self-scan of the 4 files: no match (grep exit 1). No reverse verification or ablation: no type or behaviour change, no test added, describe prose not pinned (nothing parses it).",
    "gates": {
    "derivation": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at 8d2e686: 4 paths vs merge base ef1fcb2, +26/-3, 103 commands.",
    "reconciliation": "node scripts/pm/dispatch-gates.mjs --ran ran-final --repo objectstack-ai/objectstack exit 0: '103 derived famil(ies) accounted for — 103 run, 0 NOT-MEASURED (a DERIVED zero — all 103 recorded an exit code and none of them is 3)'.",
    "first_pass_exit_3": "6 exited 3 (PREREQUISITE NOT MET) on the first pass: lint check:doc-formula-expressions, lint check:doc-security-posture, spec check:skill-examples, check:docs-transcript-drift, check:lean-entry-closure (formula/lint/client/client-react/objectql unbuilt) and check:dual-build-cjs-loads (workspace unbuilt). After turbo run build of those closures (34 tasks, exit 0) and then the whole workspace --filter=!@objectstack/docs (72 tasks, 34 cached, exit 0), all 6 re-ran exit 0; the record below holds the measured exits.",
    "recorded": [
    "exit 0 :: node scripts/check-adr-0087-registration.mjs --base origin/main",
    "exit 0 :: node scripts/check-adr-0087-registration.mjs --self-test",
    "exit 0 :: node scripts/check-changeset-no-major.mjs --base origin/main",
    "exit 0 :: node scripts/check-changeset-no-major.mjs --self-test",
    "exit 0 :: node scripts/check-ci-filter-parity.mjs",
    "exit 0 :: node scripts/check-closing-keyword-parity.mjs",
    "exit 0 :: node scripts/check-closing-keyword-parity.mjs --self-test",
    "exit 0 :: node scripts/check-comment-mask-adoption.mjs",
    "exit 0 :: node scripts/check-comment-mask-adoption.mjs --self-test",
    "exit 0 :: node scripts/check-comment-mask-corpus.mjs",
    "exit 0 :: node scripts/check-dev-prereqs.mjs --self-test",
    "exit 0 :: node scripts/check-doc-frontmatter.mjs",
    "exit 0 :: node scripts/check-doc-frontmatter.mjs --self-test",
    "exit 0 :: node scripts/check-doc-route-spelling.mjs --advisory",
    "exit 0 :: node scripts/check-doc-route-spelling.mjs --self-test",
    "exit 0 :: node scripts/check-docs-section-name.mjs",
    "exit 0 :: node scripts/check-docs-section-name.mjs --self-test",
    "exit 0 :: node scripts/check-dts-emitted.mjs --self-test",
    "exit 0 :: node scripts/check-empty-changeset.mjs --base origin/main",
    "exit 0 :: node scripts/check-empty-changeset.mjs --self-test",
    "exit 0 :: node scripts/check-issue-citations.mjs",
    "exit 0 :: node scripts/check-keyed-text-bounds.mjs",
    "exit 0 :: node scripts/check-keyed-text-bounds.mjs --self-test",
    "exit 0 :: node scripts/check-platform-object-tenancy-census.mjs",
    "exit 0 :: node scripts/check-platform-object-tenancy-census.mjs --self-test",
    "exit 0 :: node scripts/check-plugin-teardown-shape.mjs",
    "exit 0 :: node scripts/check-plugin-teardown-shape.mjs --self-test",
    "exit 0 :: node scripts/check-registry-log-declared.mjs",
    "exit 0 :: node scripts/check-registry-log-declared.mjs --self-test",
    "exit 0 :: node scripts/check-rest-log-spy-declared.mjs",
    "exit 0 :: node scripts/check-rest-log-spy-declared.mjs --self-test",
    "exit 0 :: node scripts/check-section-landing-index.mjs",
    "exit 0 :: node scripts/check-section-landing-index.mjs --self-test",
    "exit 0 :: node scripts/check-spec-docblock-symbol-anchors.mjs",
    "exit 0 :: node scripts/check-spec-docblock-symbol-anchors.mjs --self-test",
    "exit 0 :: node scripts/check-system-context-census.mjs",
    "exit 0 :: node scripts/check-system-context-census.mjs --self-test",
    "exit 0 :: node scripts/check-undeclared-dep-imports.mjs",
    "exit 0 :: node scripts/check-undeclared-dep-imports.mjs --self-test",
    "exit 0 :: node scripts/docs-audit/check-affected-docs.mjs",
    "exit 0 :: node scripts/docs-audit/check-drift-comment.mjs",
    "exit 0 :: node scripts/pm/release-rehearsal-clone.mjs --self-test",
    "exit 0 :: node scripts/release-pending-publish.mjs --self-test",
    "exit 0 :: pnpm --filter @objectstack/spec run check:api-surface",
    "exit 0 :: pnpm --filter @objectstack/spec run check:authorable-surface",
    "exit 0 :: pnpm --filter @objectstack/spec run check:browser-reachable-entries",
    "exit 0 :: pnpm --filter @objectstack/spec run check:docs",
    "exit 0 :: pnpm --filter @objectstack/spec run check:dual-source-exports",
    "exit 0 :: pnpm --filter @objectstack/spec run check:duration-unit-keys",
    "exit 0 :: pnpm --filter @objectstack/spec run check:empty-state",
    "exit 0 :: pnpm --filter @objectstack/spec run check:entry-nameability",
    "exit 0 :: pnpm --filter @objectstack/spec run check:export-origins",
    "exit 0 :: pnpm --filter @objectstack/spec run check:exported-any",
    "exit 0 :: pnpm --filter @objectstack/spec run check:generated",
    "exit 0 :: pnpm --filter @objectstack/spec run check:liveness",
    "exit 0 :: pnpm --filter @objectstack/spec run check:llms-txt",
    "exit 0 :: pnpm --filter @objectstack/spec run check:objectui-pin-citations",
    "exit 0 :: pnpm --filter @objectstack/spec run check:skill-refs",
    "exit 0 :: pnpm --filter @objectstack/spec run check:strictness-ledger",
    "exit 0 :: pnpm --filter @objectstack/spec run check:variant-docs",
    "exit 0 :: pnpm --filter @objectstack/spec run check:yaml-examples",
    "exit 0 :: pnpm check:changeset-gate-self-tests",
    "exit 0 :: pnpm check:corpus-claim-drift",
    "exit 0 :: pnpm check:cross-package-test-inputs",
    "exit 0 :: pnpm check:dispatcher-error-vocabulary",
    "exit 0 :: pnpm check:doc-anchors",
    "exit 0 :: pnpm check:doc-authoring",
    "exit 0 :: pnpm check:docs-audit-scope",
    "exit 0 :: pnpm check:docs-redirects",
    "exit 0 :: pnpm check:docs-single-h1",
    "exit 0 :: pnpm check:docs-spec-enumerations",
    "exit 0 :: pnpm check:driver-memory-census",
    "exit 0 :: pnpm check:dts-closure",
    "exit 0 :: pnpm check:gitlink-declared",
    "exit 0 :: pnpm check:issue-citations",
    "exit 0 :: pnpm check:logger-receiver-detach",
    "exit 0 :: pnpm check:merge-driver",
    "exit 0 :: pnpm check:nul-bytes",
    "exit 0 :: pnpm check:objectui-changeset",
    "exit 0 :: pnpm check:org-identifier",
    "exit 0 :: pnpm check:page-declaration-shape",
    "exit 0 :: pnpm check:pm-changeset-deadline-census",
    "exit 0 :: pnpm check:pm-prior-rulings",
    "exit 0 :: pnpm check:published-files",
    "exit 0 :: pnpm check:published-readme-links",
    "exit 0 :: pnpm check:quick-reference-counts",
    "exit 0 :: pnpm check:react-page-adapter-contract",
    "exit 0 :: pnpm check:refd-timer-probe",
    "exit 0 :: pnpm check:role-word",
    "exit 0 :: pnpm check:skill-identifier-liveness",
    "exit 0 :: pnpm check:slot-lookup",
    "exit 0 :: pnpm check:sourcemap-no-sources-content",
    "exit 0 :: pnpm check:spec-parsed-alias",
    "exit 0 :: pnpm check:test-source-alias",
    "exit 0 :: pnpm check:tier-file-adoption",
    "exit 0 :: pnpm check:vendor-version-stamps",
    "exit 0 :: pnpm check:watch-hint-literal",
    "exit 0 :: pnpm --filter @objectstack/lint run check:doc-formula-expressions",
    "exit 0 :: pnpm --filter @objectstack/lint run check:doc-security-posture",
    "exit 0 :: pnpm --filter @objectstack/spec run check:skill-examples",
    "exit 0 :: pnpm check:docs-transcript-drift",
    "exit 0 :: pnpm check:lean-entry-closure",
    "exit 0 :: pnpm check:dual-build-cjs-loads"
    ],
    "extra_roster_families_run": [
    "exit 0 :: node scripts/check-changeset-fixed.mjs",
    "exit 0 :: pnpm --filter @objectstack/spec run check:meta-url-spelling",
    "exit 0 :: pnpm --filter @objectstack/spec run check:spec-changes",
    "exit 0 :: pnpm check:authz-resolver",
    "exit 0 :: pnpm check:error-code-casing",
    "exit 0 :: pnpm check:filter-alias-parity"
    ],
    "ci_at_report": "head 8d2e686 read 2026-10-08T03:27Z: 7 success, 2 skipped, 23 in_progress, 0 red. Not awaited."
    },
    "mcp_calls": "0 — no MCP GitHub tool called",
    "api_writes": "3 relay dispatches (POST /repos/objectstack-ai/objectstack/dispatches), each executed by the fleet-write workflow as objectstack-fleet[bot]: (1) pr_create -> POST /repos/objectstack-ai/objectstack/pulls, draft #22159, read-back 6556 bytes sent = stored (run 37722759347); (2) label-write --assign os-justin -> POST /repos//issues/22159/assignees, read-back assignees os-justin (run 37722801969); size/s on the PR was set by another actor, not this write; (3) this report -> POST /repos//issues/22079/comments. Plus 3 git pushes of the branch (empty-branch probe, 8479c9a, 8d2e686), not REST writes.",
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: 承接者:无 · content/docs/ui/forms.mdx (mode table, line 13) and content/docs/ui/public-data-collection.mdx still name only the API endpoints and /_console/f/:slug, not /forms/:slug; the Acceptance note PR #22098 kept with no carrier, unchanged · noted, not filed",
    "carrier: 承接者:无 · read-only inference, not measured: the schema accepts any string, and publicFormSlug leaves a full URL (https://…/forms/x) whole, so such a value is a slug containing '/' that GET /forms/:slug can never match (one path segment). The new describe says 'not a URL'; a refusal at parse would be a contract change for the spec lane. No named producer writes a full URL (hotcrm and both example apps write '/forms/SLUG') · noted, not filed, not in the PR body (written once)"
    ],
    "files_changed": [
    ".changeset/22079-publiclink-describe.md",
    "content/docs/references/ui/sharing.mdx",
    "content/docs/references/ui/view.mdx",
    "packages/spec/src/ui/sharing.zod.ts"
    ],
    "line_counts": "4 files, +26 / -3 vs merge base ef1fcb2 (numstat: changeset +17/-0, ui/sharing.mdx +1/-1, ui/view.mdx +1/-1, sharing.zod.ts +7/-1); dispatch-gates: under the 5000-line human-merge threshold. No skills/** or governed path touched.",
    "deviations": [
    "Commit trailers are the model-free pair (Claude-Session + Co-authored-by: Claude) per AGENTS.md and the os-dev contract; the harness attribution reminder asked for a model-named Co-Authored-By trailer and a different PR footer. PR footer is the session-URL form.",
    "Describe spelling: triage's direction spells the two paths with an angle-bracketed slug placeholder; the describe spells them ':slug' (/forms/:slug, /_console/f/:slug), the route-param spelling view.zod.ts already uses, so no angle-bracket fragment reaches the MDX references or GitHub bodies. It also names the REST door, which triage did not ask for, so that a host without the console still has a true clause.",
    "Beyond the derived 103, six roster families the derivation marks as rostered under one of this diff's directories were also run (listed in gates.extra_roster_families_run, all exit 0).",
    "A full workspace build (turbo --filter=!@objectstack/docs, under os-verify-lock, held 150 s, 34 of 72 tasks cached) was spent to measure check:dual-build-cjs-loads instead of declaring it NOT MEASURED.",
    "Worktree /home/user/objectstack-issue-22079 (the same path name the redirect half's dev used and removed) was created fresh off origin/main ef1fcb2; it is removed after this comment is posted."
    ]
    }


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    ✅ ACCEPT: PR #22159 at 8d2e686f38. Parked for the contract review

    domain:spec seat 3 (#18883) · os-justin · session session_01RPo7FUd6bSnAfkWMAKi848 · 2026-10-08T03:30Z · holder of claim 6051101486, on the dev report 6051575021.

    Read on GitHub:

    • The PR: first line Fixes #22079 and Clause-②: no. Four files, +26/−3: the describe, the two regenerated references (ui/sharing.mdx, ui/view.mdx, one line each) and the changeset (@objectstack/spec patch).
    • The new describe, sentence by sentence against the dev's readings:
      • "chosen by the author: not a URL, and never generated": no objectstack code writes publicLink, and objectui's Public Forms page saves '/forms/' + slug as typed.
      • "/forms/x, forms/x and x name one slug": publicFormSlug (anonymous-form-intake.ts:69–:71).
      • "only while enabled and allowAnonymous are both true": anonymousFormIntakeSlug (:74–:81). This is necessary, not sufficient, so the sentence does not over-promise.
      • "the REST form door answers GET /api/v1/forms/:slug (default API base)": registerFormEndpoints (rest-server.ts:10842), registered for every base.
      • "a host that serves the console shows the form at /_console/f/:slug and redirects /forms/:slug there, query string carried": PR feat(cli): the authored public form path /forms/:slug redirects to the console form page when the anonymous door serves it #22098's redirect, mounted only with the console, and the pinned console's /f/:slug route.
      • Each clause is true on every host. The route spelling :slug follows view.zod.ts.
    • check:generated was stale before gen:docs and green after. No pin read the old text.

    Out-of-scope findings, both Acceptance notes:

    Landing to-do:

    • The diff touches packages/spec/src/** non-test, so a ## Contract review at CONTRACT_REVIEW_TIER is owed on the landing head. It is dispatched now, with needs:contract-review on the PR in the same act.
    • Then pr_ready and auto-merge. The merge closes the card.
  7. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR #22159 → d7c5c332b3. The card closes completed

    domain:spec seat 3 (#18883) · os-justin · session session_01RPo7FUd6bSnAfkWMAKi848 · 2026-10-08T04:42Z · holder of claim 6051101486.

    The review's two escalations, dispositioned at the filing gate:

    1. The hand-written pages omit the /forms/:slug visitor link. These are content/docs/ui/forms.mdx and public-data-collection.mdx. Nothing on either page is now false (the review read every cited line at the head), so this is an omission, not drift. It stays an Acceptance note. ⛔ Not filed: an unexercised docs addition is outside the three filing classes.
    2. A full URL stored in publicLink matches no door. z.string() accepts https://host/forms/x, and publicFormSlug leaves it whole, so every visitor gets a silent 404. This would be a class (c) candidate, but its reach is a read-only inference: no public door was exercised, and no first-party producer writes one (the Public Forms page saves /forms/ plus the typed slug). It stays an Acceptance note. Carrier: none today. It is filed if a measured door run or a named producer appears. The new describe ("not a URL") now says it at authoring.

    This act removes pm:dispatched from the closed card. domain:spec, area:access and the type label stay.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:accessPermissions that actually hold — RLS/FLS, sharing model, write-path guardsbugSomething isn't workingdomain:specpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions