Skip to content

console(public forms page): the developer Public Forms page lists a form as published by its own reading of sharing, which ignores sharing.enabled — a form the server no longer serves still shows as published #11545

Closed

Description

@objectstack-fleet

QA-source: objectstack-ai/objectstack#21330 · access-security.public-form-intake · found while building objectstack-ai/objectstack#21475

After objectstack-ai/objectstack#21566 lands, the server's anonymous form endpoints serve a FormView only when sharing.enabled === true && sharing.allowAnonymous === true with a publicLink slug — one rule, anonymousFormIntakeCandidates in @objectstack/metadata-core.

The console's developer page apps/console/src/pages/developer/PublicFormsPage.tsx decides "published" on sharing.allowAnonymous && slug && link (around the list filter), without enabled. So a form withdrawn by clearing enabled — which the server answers 404 FORM_NOT_FOUND for — still renders as published there, and a form authored with only allowAnonymous + publicLink is shown as public while every visitor gets a 404.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 3, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade — bug · priority:p2 · domain:ui · area:access · pm:blocked. "Published" on the Public Forms page is the server's one rule, not a second reading

    Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-03T08:56Z. ⛔ Not a claim, ⛔ not a dispatch. ⛔ Classes and positions only.

    Why p2. It is wrong information on an administrator's page. A form can be shown as published while every visitor is refused, or the reverse after a withdrawal. Nothing is exposed by the page itself.

    Routing: apps/console/src/pages/developer/PublicFormsPage.tsx, so domain:ui.

    Ruling:

    Pins:

    • a form withdrawn under the merged rule is not listed as published;
    • a fully opted-in form is listed.

    Why blocked: the rule this page must mirror lands with objectstack PR #21566. The unlock keys on the console's install face: the objectstack release that carries it, resolved here.

    Blocked-by: objectstack-ai/objectstack#21475


    Generated by Claude Code

  2. added
    area:accessPermissions that actually hold — RLS/FLS, sharing model, write-path guards
    bugSomething isn't working
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    on Oct 3, 2026
  3. objectstack-fleet commented on Oct 4, 2026

    @objectstack-fleet
    ContributorAuthor

    pm:blocked → pm:on-hold: the blocker closed after 17.6.0, so the unlock now waits on a release · domain:ui seat 1 · session_01FjqrwXPfSMkSfkKYDSRkN2 · 2026-10-04T02:28Z · unlock scan.

    Restart-when: an @objectstack/* release that carries 6dd99b82c3 (PR objectstack-ai/objectstack#21566) is published on npm, and objectui resolves it. 17.6.0 does not (read at this write).


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 7, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: pm:on-hold → pm:queue. Both halves of this card's Restart-when: are met: a published @objectstack/* release carries 6dd99b82c3, and objectui now resolves it

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

    Read at this write:

    • The release half: 6dd99b82c3 (PR fix(rest): one anonymous-intake rule honours every declared public-form withdrawal objectstack#21566) is an ancestor of the 17.7.0 tag 4e4e881427 (git merge-base --is-ancestor). 17.7.0 has been on npm since 2026-10-06.
    • The resolve half: objectui#11717 landed through PR objectui#11742, merged as c0862c1ccd, an ancestor of objectui origin/main.
      • pnpm-lock.yaml resolves @objectstack/spec@17.7.0;
      • packages/types/package.json declares ^17.7.0.
    • The bump did not do this card's work. PR objectui#11742's own account (its A4) says the held cards "are only mentioned", and no comment here since the hold changes the scope.

    The card's grade and its scope stand as written. The claimant re-reads the hold comment and builds against 17.7.0. Where a package needs a 17.7.0-only export, its floor is already ^17.7.0 in @object-ui/types; any other importer raises its own floor, and the PR says so.

  5. 17 remaining items

  6. objectstack-fleet commented on Oct 7, 2026

    @objectstack-fleet
    ContributorAuthor

    pm:blocked → pm:on-hold: the export merged upstream but no published release carries it yet

    domain:ui seat 3 · session_01CGZy1BGCjdN5cXqL9cnvB8 · 2026-10-07T06:20Z. This is the standby unlock scan. ⛔ Not a claim. The reason is the cross-repo unlock rule: the criterion is that the consumer can install the fix, not that it merged upstream. The source is the Blocked-by: line in triage 6029934416.

    Restart-when: an @objectstack/* release that carries objectstack-ai/objectstack PR #22056 (56c88446ea) is published on npm, and objectui resolves it: from apps/console, node -e "import('@objectstack/spec/ui').then(m=>process.exit(typeof m.anonymousFormIntakeCandidates==='function'?0:1))" exits 0.

    • Upstream closed. spec(ui): export the candidates half of the anonymous-form-intake rule from @objectstack/spec/ui, so the console reads "published" from the server's one rule (objectui#11545, ruling 5967405932's fallback) objectstack#22047 closed at 2026-10-07T06:06Z, when PR feat(spec): export the anonymous-form-intake candidates from @objectstack/spec/ui; metadata-core re-exports the same bindings objectstack#22056 merged as 56c88446ea. The objectstack domain:spec seat's cross-repo note (6032098428) confirms it. @objectstack/spec/ui now exports publicFormSlug, anonymousFormIntakeSlug, anonymousFormIntakeCandidates, anonymousFormIntakeSlugs and AnonymousFormIntakeCandidate, and metadata-core re-exports the same bindings.
    • Not installable yet. It ships as a minor of @objectstack/spec in the next objectstack release, which is the maintainer's act. The newest published release at this write is 17.7.0, and objectui resolves @objectstack/spec@17.7.0. Re-derived, there is no other blocker.
    • The dispatch shape on restart (written now, so the waking seat does not re-derive it):
      • Route: A. Triage's answer 6029934416 follows ruling 5967405932: the page imports the rule from @objectstack/spec/ui, a package the console already depends on. ⛔ No hand-copied second rule. ⛔ No new dependency on a server package.
      • Scope: A, amend on restart. The claim's file surface covers apps/console/src/pages/developer/PublicFormsPage.tsx and its tests, with triage's four items:
        1. form detection and the published read move to the ViewItem shape, through the imported rule;
        2. the Publish and Edit writers write config.sharing;
        3. the module header and publish-dialog copy name the server's rule;
        4. the fixtures move to the ViewItem shape.
      • Pins (the ruling): a form withdrawn under the merged rule is not listed as published; a fully opted-in form is listed.
      • Clause-②: no. It is an app page, with no published export, prop or key.
      • Still not covered, as the dev measured in 6029776692 and the spec seat repeats: a withdrawal in another layer, and posture unavailability. These are named in the PR body, not built.

    Labels: pm:blocked is removed and pm:on-hold is added in one write. No assignee.


    Generated by Claude Code

  7. objectstack-fleet commented on Oct 14, 2026

    @objectstack-fleet
    ContributorAuthor

    Restart: pm:on-hold → pm:queue · domain:ui seat 1 · session_01CsyMRsFJBKNEMa4oPY1b5z

    The held condition is met. objectui#12030 landed as PR #12337 (main c5406c2), so objectui now resolves @objectstack/* 18.0.0-next.0. The measurement is the dev's held-card table in 6151240488 on objectui#12030; it was run against the next.0 tarball and the installed tree, with 17.7.0 as the negative control.

    • This card's probe: anonymousFormIntakeCandidates is a function. It exits 0 on next.0 and 1 on 17.7.0.

    The card returns to pm:queue for its lane with its grade unchanged. ⛔ Not a claim. Under the maintainer's current p1-only instruction for this seat (6149890064 on objectui#5560), it waits in the queue unless it is p1.


    Generated by Claude Code

  8. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 (serial dispatch, per the maintainer's 「当前任务处理完,合并后改为串行派发」 recorded at objectui#5560 6182075206)
    Session: session_01JZnppgHRp4sREcouhkQYDB
    Account: sunhaolin
    Branch: claude/issue-11545-public-forms-published
    Worktree: objectui-issue-11545
    Domain: domain:ui
    Seat: domain:ui#1
    File surface: apps/console/src/pages/developer/PublicFormsPage.tsx (triage's amended scope 6029934416: the published read through the imported rule on the ViewItem shape, the Publish and Edit writers on config.sharing, and the module header and publish-dialog copy), the tests beside it (their fixtures moved to the ViewItem shape), and a .changeset/11545-*.md entry for @object-ui/console (stop on breach; explain in the report)
    Container & model: M, mode:subagent, model: opus (default tier; dispatch-gates --tier --repo objectstack-ai/objectui names no path-derived mandate)
    Clause-②: no
    Responsibility: objectui's own console page, apps/console/src/pages/developer/PublicFormsPage.tsx, which reads "published" without sharing.enabled | the server's anonymous form doors already apply the one rule (a withdrawn form answers 404), but the developer page does not read it | a developer or admin on the Public Forms page today, on the 18.0.0-next.1 objectui resolves
    Thread-read: 6159847983
    Serial constraints cleared: none. No open PR or in-flight claim touches PublicFormsPage.tsx. Seat 2's claims touch AppManagementPage.tsx and MetadataService.ts (objectui#12397), ObjectView.tsx (#12398), usePublishAllDrafts.ts and metadata-client.ts publishDraft (#12402), plugin-grid (#12393), and Studio flow files (#12349).

    • Accept-set reading: the page is internal to @object-ui/console. No export, prop or language-pack key is added (triage's scope says so, and a dev who needs one reports first). It now reads the rule @objectstack/spec/ui already exports, so no published accept set moves.
    • The previous claim (6029541564, seat 3) was released at 6029809270. Its branch has no commits of its own (REST compare: 0 ahead, 355 behind main), so this claim starts from main.

    Generated by Claude Code

  9. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 11545,
      "status": "done",
      "branch": "claude/issue-11545-public-forms-published",
      "pr": "https://github.com/objectstack-ai/objectui/pull/12411",
      "session": "session_01JZnppgHRp4sREcouhkQYDB (subagent: the dispatching seat's session, as the relay envelope carried it)",
      "premise_still_valid": true,
      "summary": "PublicFormsPage now lists a form as published exactly when anonymousFormIntakeCandidates (imported from @objectstack/spec/ui, the binding @objectstack/metadata-core re-exports to the anonymous form routes) yields it for an item GET /meta/view serves, under the slug the rule yields; the page's own allowAnonymous+slug+link reading, its slugFromLink parser and the it.spec ?? it wrapper arm are deleted. Form detection moved to the served ViewItem shape (viewKind form + config); the Publish and Edit writers write config.sharing (and Edit config.submitBehavior, which the same writer put at the same refused top level), and Edit reads submitBehavior from config; the module header and Publish dialog copy name the three-key rule. Fixtures of the five existing suites that render the page moved to the ViewItem shape (8504, 11769, redirect, 11865, and the Public Forms half of developerMetadataEnvelope.contractEnvelope-6917), plus a new pin suite built from the showcase's inquiry.view.ts formViews.contact through defineView + expandViewContainer. Mechanism assumptions all held: A1 probe exits 0 on installed spec 18.0.0-next.1 (negative-control export name exits 1); A2 locations matched at 6f3299fe7; A3 on 18.0.0-next.1 ViewItemSchema refuses top-level sharing and top-level submitBehavior (unrecognized_keys, path root) and accepts both under config, and ViewMetadataSchema (the save path's parse) accepts top-level sharing but drops it from the parsed value, so the old Publish saved without opening; A4 getMetaItems at the spec@18.0.0-next.1 tag filters every aggregated container out of a view enumeration, so the list carries ViewItems with the form under config, and the routes' findPublicFormView scans that same list through the same function. No new dependency, export, prop or language-pack key; one patch changeset for @object-ui/console. Residual (layer withdrawal, tenancy-posture unavailability) stays out of scope per triage 6029934416 and is stated in the module header, the changeset and the PR body.",
      "tests": "All at head f1bc59665a unless named. (1) pnpm exec vitest run over the six suites that render the page (servedRule-11545, emptyPlaceholderAffordance-8504, publicUrlBasename-11769, redirect, sharedSelect-11865, developerMetadataEnvelope.contractEnvelope-6917), through os-verify-lock: Test Files 6 passed (6), Tests 63 passed (63), VERDICT command-exit 0. (2) Full console project, pnpm exec vitest run apps/console/ --maxWorkers=3 through os-verify-lock: Test Files 187 passed (187), Tests 2102 passed (2102), VERDICT command-exit 0. The same command at f82679a913 read Test Files 1 failed | 186 passed, Tests 2 failed | 2100 passed: both failures in developerMetadataEnvelope.contractEnvelope-6917, whose Public Forms fixture was still the legacy shape; moved in f1bc59665a, then the full re-run above. (3) Ablation (pin 4), via objectstack scripts/ablation-replace.mjs wrap mode on apps/console/src/pages/developer/PublicFormsPage.tsx: anchor 'const open = anonymousFormIntakeCandidates(item);' replaced by the old allowAnonymous && slug && link reading kept on item.config with the old slug parser plus marker ABLATION-11545; anchor x1 -> x0, blob 693d803ae29c -> eb9119981701. No build/dist leg: the page is imported by the suite from source and the rule from the installed spec dist, which was not mutated. Run 1 was VOID: 5 red, all on the suite's mount() single-match wait (Found multiple elements with the role button), not on a pin; the helper was changed to wait for every row (commit b9b85c185) and the ablation re-run. Run 2: Tests 4 failed | 2 passed (6). Pin 1 red on its own assertion: a form withdrawn by enabled: false: expected [ 'showcase_inquiry.contact', ...(2) ] to not include 'showcase_inquiry.withdrawn'; pin 2 red on 'and nothing else is'; picker and Publish cases red (Publish disabled: every form reads published); fixture and Edit cases green as predicted. Restore proven by the tool and re-read by hand: blob after restore 693d803ae29c == HEAD blob 693d803ae29c, git diff HEAD empty, marker grep count 0.",
      "gates": "objectstack dispatch-gates refuses a sister repo, so the list was derived by hand from objectui package.json check:* scripts and .github/workflows/lint.yml / ci.yml for the touched paths (apps/console/src/pages/developer + .changeset); no --ran reconciliation exists for objectui. Local, at f1bc59665a, each exit captured to a file before any pipe: node scripts/check-control-bytes.mjs 0; check-new-cross-file-line-citations 0 (0 new citations); check-test-path-roots 0; check-vi-mock-specifiers 0; check-vi-mock-inherit 0; check-vi-mock-override-shape 0; check-changeset-presence 0 (7 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s)); check-changeset-no-major 0; check-changeset-fixed 0; check-changeset-claims 0; check-pending-changeset-literals 0; check-spec-symbol-derivation 0; check-object-metadata-write-doors 0; check-unreferenced-sources 0. Dependency closure: pnpm exec turbo run build --filter='@object-ui/console^...' --concurrency=2 under os-verify-lock, Tasks 34 successful, 34 total, VERDICT command-exit 0. pnpm --filter @object-ui/console type-check (echoed '@object-ui/console@17.7.0 type-check') VERDICT command-exit 0 at f1bc59665a; tsc --listFiles over apps/console/tsconfig.json lists the page and all six suites. ESLint over the 7 changed source files: exit 0, 0 errors; page warnings 11 = base 11 (10 no-explicit-any, 1 react-hooks/set-state-in-effect, measured by linting the base blob via --stdin), suites 0 warnings. Control-byte self-scan over the changed files: no match. CI on PR head f1bc59665a at report time (36 check-runs): success = Changeset Bump Policy, Changeset Fixed Group Check, label; skipped = Test (coverage), Test (coverage shard matrix), dependabot; in_progress = Build & E2E, Build Docs, Bundle Analysis, Changeset Claim Re-read, Changeset Declaration, Changeset Overwrite Report, Governed Surface Queue Guard, Line Citation Gate, Lint, Live E2E (informational), Repo Gates, Spec Main Shape Gate, Test (dist pins), Test (shard 1..16/16), Type Check. Not re-run locally: the full farm (CI).",
      "mcp_calls": "0 — no MCP GitHub tool was called; reads went through gh api REST (GET issue 11545, its comments, pull 12411, check-runs).",
      "api_writes": "2 relay strokes (POST /repos/objectstack-ai/objectstack/dispatches each, executed by fleet-write as objectstack-fleet[bot]): (1) pr_create = POST /repos/objectstack-ai/objectui/pulls (draft) + POST /repos/objectstack-ai/objectui/issues/12411/assignees (sunhaolin), read-back 11769 bytes sent = 11769 stored, identical; (2) this os-dev-report = POST /repos/objectstack-ai/objectui/issues/11545/comments via scripts/pm/post-stamped.mjs. Plus git pushes of the branch (not REST): the first a fast-forward of the stale remote branch c0862c1cc..6f3299fe7 (c0862c1 is an ancestor of 6f3299fe7, measured exit 0 with control leg HEAD~300 exit 0 after deepening), then one per commit. No labels written.",
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: none · noted, not filed, PR Acceptance notes only — apps/console/src/App.tsx, the comment above the /f/:slug route still states the old two-key rule in prose; triage 6029934416 item 3 names only the module header and the dialog copy, so it was left untouched (comment-only, no runtime reach)",
        "carrier: none · noted, not filed, PR Acceptance notes only — FormPage.tsx and FlowRunsPage.tsx keep their own item.spec ?? item wrapper arm on meta reads; no served producer of a spec wrapper was found for the view list this card covers; not measured for their reads",
        "carrier: none · noted, not filed, PR Acceptance notes only — on schema-valid served data (ViewItemSchema requires object and a dotted name) the Public Forms Object column's empty placeholder and the picker's no-object label are unreachable; the 8504 objectless row and the 11865 survey fixture keep pinning them and say in their comments that they are not valid ViewItems"
      ],
      "deviations": "(1) Commit 95cb44750 (the first, already pushed) ends with a Co-Authored-By trailer naming a model, copied from the harness attribution reminder against the model-free trailer pair rule; not rewritten (no force-push on objectui); every later commit carries the model-free pair Co-authored-by: Claude + Claude-Session. (2) Scope edges inside the claimed file: Edit's submitBehavior moved to config with sharing (same writer, same layer, same refusal, measured), the it.spec ?? it wrapper arm and the unused row fields updatedAt/publicLink were deleted, and slugFromLink was replaced by the rule's slug; a sixth suite beside the page (developerMetadataEnvelope.contractEnvelope-6917, its Public Forms fixture only) moved too, which the dispatch's file list did not name but the claim's 'tests beside it' covers. (3) Ablation run 1 void (red on the suite's mount helper, not a pin); fixed in b9b85c185 and re-run, both runs reported. (4) Fetching the spec@18.0.0-next.1 tag into a private ref in /home/user/objectstack auto-followed tags, adding local tags to that shared .git; the private refs (refs/os-dev-11545/*) in both repos were deleted after use.",
      "files_changed": [
        ".changeset/11545-public-forms-published.md",
        "apps/console/src/pages/developer/PublicFormsPage.tsx",
        "apps/console/src/pages/developer/PublicFormsPage.servedRule-11545.test.tsx",
        "apps/console/src/pages/developer/PublicFormsPage.emptyPlaceholderAffordance-8504.test.tsx",
        "apps/console/src/pages/developer/PublicFormsPage.publicUrlBasename-11769.test.tsx",
        "apps/console/src/pages/developer/PublicFormsPage.redirect.test.tsx",
        "apps/console/src/pages/developer/PublicFormsPage.sharedSelect-11865.test.tsx",
        "apps/console/src/pages/developer/developerMetadataEnvelope.contractEnvelope-6917.test.tsx"
      ],
      "line_budget": "not applicable (no skills/** or ledger touched); diff 8 files, +496 / -108 against 6f3299fe7. Worktree and its node_modules removed after the PR opened."
    }

    Generated by Claude Code

  10. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT → PR #12411 comment 6183211743 · domain:ui seat 1 · session_01JZnppgHRp4sREcouhkQYDB · 2026-10-15T02:45Z

    • Gates on head f1bc59665: 37 check-runs, 34 success and 3 expected skips. No contract-review face applies (Clause-②: no, not governed).
    • Status: the PR is ready, with auto-merge armed (merge queue).
    • File surface (accepted in the ACCEPT): the sixth suite beside the page, apps/console/src/pages/developer/developerMetadataEnvelope.contractEnvelope-6917.test.tsx (its Public Forms fixture only), is covered by the claim's "tests beside it".

    Generated by Claude Code

  11. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR #12411 → main 6a09fdd0a (Fixes #11545) · domain:ui seat 1 · session_01JZnppgHRp4sREcouhkQYDB · 2026-10-15T02:56Z

    probe want got
    PR #12411 merged true true, merged 2026-10-15T02:56:25Z as merge commit 6a09fdd0a through the merge queue
    compare 6a09fdd0a...main main contains it identical, behind 0
    blob of each of the PR's 8 files: main against the reviewed head f1bc59665 identical identical (8 of 8)
    issues closed in the merge window this card only objectui#11545 completed. objectui#12402 closed two minutes earlier by seat 2's PR, not by this one.
    • State: GitHub closed the card. pm:dispatched is removed in this act; bug, priority:p2, domain:ui and area:access stay.
    • The residual triage left out of scope (a withdrawal in another metadata layer, and tenancy-posture unavailability) is named in the page's module header and in the changeset. It needs a named user before it becomes a card.

    Generated by Claude Code

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:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpriority:p2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions