Skip to content

console(public forms page): the copy, iframe and React snippets build the anonymous URL as ${origin}/console/f/<slug>, but every first-party mount serves the console at /_console/ — build it from the router basename #11769

Description

@objectstack-fleet

Filing gate: ① a product defect, class (a), with reach through a named real producer: the developer Public Forms page (apps/console/src/pages/developer/PublicFormsPage.tsx), which hands every author the link they paste into a website. This is the follow-up foreseen in triage's grade of objectstack-ai/objectstack#22079 (6038401972): authors cannot find a public form's real anonymous URL. Filed by the triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015, session_01AavokzJ5DndAwitDXvKy4U). ⛔ Not a claim.

What the page builds (read on objectui main)

  • PublicFormsPage.tsx:194 builds formatPublicUrl = (slug) => `${origin}/console/f/${slug}`. The "copy URL", the iframe snippet (:195) and the React snippet (:197) all use it.
  • The console's own router resolves its basename from <base href> (apps/console/src/App.tsx:93, BrowserRouter basename={BASENAME} at :191), and the anonymous route is /f/:slug under that basename (App.tsx:242).

Where the console is actually mounted (read)

So on every first-party mount, the URL this page offers is /console/f/<slug>, which is not where the form is served. ⛔ The page's runtime answer at /console/f/<slug> was not measured. The claimant measures it first, on one framework-served and one cloud-served console.

Done when

  • The page builds the anonymous URL from the console's own basename (<origin><basename>/f/<slug>), not from a hard-coded prefix. The copy URL, the iframe snippet and the React snippet all agree.
  • Pins:
    • with basename /_console, the page offers <origin>/_console/f/<slug>;
    • with a root-mounted console it offers <origin>/f/<slug>;
    • the snippet text matches the copied URL.

Related

Activity

  1. added
    bugSomething isn't working
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    area:devpathThe road — create, dev, verify, publish/install, connect an agent, iterate
    on Oct 7, 2026
  2. objectstack-fleet commented on Oct 7, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 2
    Session: session_01CGZy1BGCjdN5cXqL9cnvB8
    Account: os-support-ai
    Branch: claude/issue-11769-public-form-url-basename
    Worktree: objectui-issue-11769
    Domain: domain:ui
    Seat: domain:ui#3
    File surface: apps/console/src/pages/developer/PublicFormsPage.tsx (formatPublicUrl at :194, the iframe and React snippets at :196–:198, the copy-URL use at :374, and the two dialog prefixes that print /console/f/ at :479 and :517, on 179f6fe); the basename source only if it must be exported to the page (apps/console/src/App.tsx, resolveBasename / BASENAME at :93–:120); the tests beside them; .changeset/11769-*.md if a released package changes. Any file outside this list: the dev reports it before opening the PR (stop on breach; explain in the report)
    Container & model: S, mode:subagent, model: opus (dispatch-gates --tier --repo objectstack-ai/objectui: no path-derived mandate; default tier)
    Clause-②: no
    Responsibility: objectui apps/console: PublicFormsPage builds every anonymous form URL as ${origin}/console/f/<slug>, a hard-coded prefix | the platform path exists: the console's router already resolves its basename from <base href> (App.tsx BASENAME), and the anonymous route is /f/:slug under it; every first-party mount serves the console at /_console/ | every author who copies a public form's URL, iframe or React snippet from the developer Public Forms page; measured on 17.7.0 by the repo:hotcrm seat (objectstack-ai/objectstack#22079): the form is served at /_console/f/<slug>
    Thread-read: none
    Serial constraints cleared: none blocking. objectui#11545 (pm:on-hold, same file, a different mechanism, not in flight) is unchanged and not merged with this card, as the card says. No open objectui PR touches the files above (read 2026-10-07T13:20Z; open: #11600, #11069). No other area:devpath card is in flight.

    Why Clause-②: no: an app page builds a URL from a value the app already resolves. No published export, prop, type member or language-pack key is expected. If one is needed, the dev reports it before opening the PR, and the seat amends this line.


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 7, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 11769,
      "status": "done",
      "branch": "claude/issue-11769-public-form-url-basename",
      "pr": "https://github.com/objectstack-ai/objectui/pull/11771",
      "session": "session_01CGZy1BGCjdN5cXqL9cnvB8 (subagent mode: the parent session id)",
      "premise_still_valid": true,
      "summary": "PublicFormsPage now builds every anonymous URL from the router: useHref('/f') returns /_console/f under a /_console basename and /f at root. One value, publicFormPath, feeds the link, Copy URL, the iframe and React snippets and both slug-field prefixes, which no longer print a literal /console/f/. App.tsx is untouched, nothing is exported, and the changeset is a patch for @object-ui/console. The premise was measured before the change on a framework-served console (@objectstack/cli 17.7.0 serve, then dev --fresh, in scratch): GET /console/f/contact-us returned 404 ENDPOINT_NOT_FOUND; GET /_console/f/contact-us returned 200, and an anonymous visitor in Chromium saw the form. The released @objectstack/console 17.7.0 bundle carries the hard-coded URL. Cloud: NOT MEASURED, because egress to cloud.objectos.ai:443 is denied by organization policy and the session has no cloud checkout. Caveat on reach: on that 17.7.0 framework runtime the page lists NO public form at all, a separate defect described in out_of_scope_findings. The URL defect is therefore masked there today, and the fixed URL could only be pinned in unit tests, not shown in a browser.",
      "tests": "On final HEAD e90d688: `pnpm exec vitest run apps/console/src/pages/developer/ apps/console/src/__tests__/orphanedPageComponentRefs-10520.test.tsx` exited 0 with Test Files 11 passed (11), Tests 95 passed (95). These are every importer of PublicFormsPage plus the component-route test. The new file PublicFormsPage.publicUrlBasename-11769.test.tsx has 12 tests: 3 mounts (/_console, root, and /_console through /apps/APP/component/developer/public-forms) times 4 pins (link and copied URL equal ORIGIN+basename+/f/SLUG; both snippets hold exactly the copied URL; both slug-field prefixes; no /console/f/ text). It renders under BrowserRouter with a basename. Three existing page tests (6917 envelope, redirect, 8504) now render with { wrapper: MemoryRouter }, with no assertion changed. Type-check: built the console closure with `turbo run build --filter='@object-ui/console^...' --concurrency=2` (exit 0, 34/34 tasks), then `pnpm --filter @object-ui/console type-check` (exit 0, zero error TS); `tsc --listFiles` includes all 5 touched tsx files. A first type-check before that build exited 2 with 653 TS2307 missing-dist errors and is not a measurement. Ablation, run once with ablation-replace.mjs after the fix was committed: the mutation was proven on disk (anchor 1 to 0, blob c8a3e7d2c580 to a new blob), and the restore was proven (blob equals HEAD, empty git diff HEAD). (1) publicFormPath forced to '/console/f': 9 failed, 3 passed of 12. The offers, prefix and no-/console pins went red on all 3 mounts, e.g. expected '/console/f/' to be '/_console/f/'. The snippet-agreement pins stayed green, as expected for a consistent hard-code. (2) Only the iframe snippet pointed at ORIGIN/console/f/SLUG: 3 failed (the snippet-agreement pin per mount), 9 passed. No build is involved: the tests import the page by relative path.",
      "mcp_calls": "0, no MCP GitHub tool was called",
      "api_writes": "3, each through the fleet-write relay (one POST /repos/objectstack-ai/objectstack/dispatches each): pr_create POST /repos/objectstack-ai/objectui/pulls (#11771, draft; read-back 9656 bytes identical); assign POST /repos/objectstack-ai/objectui/issues/11771/assignees os-support-ai via label-write.mjs (read-back matches); this os-dev-report comment POST /repos/objectstack-ai/objectui/issues/11769/comments. Not REST: 2 git pushes to the branch (the empty probe, then e90d688).",
      "open_questions": [],
      "out_of_scope_findings": [
        "class: a · reach: a public door gives a wrong answer. On a framework-served console (@objectstack/cli 17.7.0 with its vendored @objectstack/console 17.7.0), Developer, then Public Forms (both /apps/setup/developer/public-forms and /apps/setup/component/developer/public-forms) shows 'No public forms yet' for a package-declared form with sharing.allowAnonymous and publicLink '/forms/contact-us'. 'Publish form…' is disabled. Measured in Chromium. · evidence: GET /api/v1/meta/view serves each view as a ViewItem with the keys name, object, viewKind, label and config. The form's sharing and sections are under config. PublicFormsPage.load reads `it?.spec ?? it` and tests sections, sharing and viewType on the item itself, so isForm is false for every served item. The runtime refuses a PUT of a bare view config with 422 and names the ViewItem shape ('or save a ViewItem record ({ name, object, viewKind, config: { … } })'), so the page's own publish and save, which spread the item and write sharing at its top level, are also suspect (NOT MEASURED, since the listing is empty). The page's tests (6917 envelope, 8504, redirect) use a { spec } fixture shape this runtime does not serve. Same page and same listing function as objectui#11545 (pm:on-hold, which is about sharing.enabled); whether this is that card's sub-issue is the seat's call. · dedupe words: Public Forms page; No public forms yet; meta.getItems view config viewKind; ViewItem config spec; PublicFormsPage listing"
      ],
      "gates": [
        {
          "command": "pnpm exec vitest run apps/console/src/pages/developer/ apps/console/src/__tests__/orphanedPageComponentRefs-10520.test.tsx (via os-verify-lock)",
          "exit": 0,
          "verdict": "Test Files 11 passed (11) · Tests 95 passed (95) · os-verify-lock: VERDICT command-exit 0"
        },
        {
          "command": "pnpm exec turbo run build --filter='@object-ui/console^...' --concurrency=2 (via os-verify-lock)",
          "exit": 0,
          "verdict": "Tasks: 34 successful, 34 total · VERDICT command-exit 0"
        },
        {
          "command": "pnpm --filter @object-ui/console type-check (via os-verify-lock, after the closure build)",
          "exit": 0,
          "verdict": "script echoed `type-check`: tsc --noEmit && tsc -b tsconfig.node.json --force · VERDICT command-exit 0 · 0 error TS"
        },
        {
          "command": "pnpm exec eslint (5 touched files)",
          "exit": 0,
          "verdict": "0 errors, 12 warnings; all 12 in PublicFormsPage.tsx and pre-existing (BASE 179f6fe 0e/12w, HEAD 0e/12w); new test file 0e/0w"
        },
        {
          "command": "node scripts/check-changeset-presence.mjs",
          "exit": 0,
          "verdict": "5 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s): .changeset/11769-public-form-url-basename.md"
        },
        {
          "command": "node scripts/check-changeset-no-major.mjs",
          "exit": 0,
          "verdict": "No changeset declares a `major` bump."
        },
        {
          "command": "pnpm check:control-bytes",
          "exit": 0,
          "verdict": "check-control-bytes: OK"
        },
        {
          "command": "pnpm check:test-path-roots",
          "exit": 0,
          "verdict": "check-test-path-roots: OK"
        },
        {
          "command": "pnpm check:changeset-claims",
          "exit": 0,
          "verdict": "No pending changeset names a file this change touches."
        },
        {
          "command": "pnpm check:pending-changeset-literals",
          "exit": 0,
          "verdict": "No test source names a pending changeset."
        },
        {
          "command": "pnpm check:new-line-citations",
          "exit": 0,
          "verdict": "VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only -> exit 0"
        },
        {
          "command": "pnpm check:vi-mock-specifiers",
          "exit": 0,
          "verdict": "check-vi-mock-specifiers: OK"
        },
        {
          "command": "pnpm check:vi-mock-inherit",
          "exit": 0,
          "verdict": "check-vi-mock-inherit: OK"
        },
        {
          "command": "pnpm check:vi-mock-override-shape",
          "exit": 0,
          "verdict": "check-vi-mock-override-shape: OK"
        },
        {
          "command": "pnpm check:phantom-deps",
          "exit": 0,
          "verdict": "scan completed, exit 0 (react-router-dom is already a declared dependency of @object-ui/console)"
        },
        {
          "command": "pnpm check:shell-escape-residue",
          "exit": 0,
          "verdict": "check-shell-escape-residue: OK"
        },
        {
          "command": "pnpm check:unreferenced-sources",
          "exit": 0,
          "verdict": "OK Every shipped source file in every covered package …"
        },
        {
          "command": "CI on e90d688 (read once at report time)",
          "exit": null,
          "verdict": "in_progress: 42 check runs, 21 success, 3 skipped, 18 in progress"
        }
      ],
      "deviations": [
        "Measurement used the published @objectstack/cli@17.7.0 and @object-ui/console@17.7.0, installed from npm into this session scratchpad (npm install --ignore-scripts), and ran `os serve` / `os dev --fresh` on ports 4769 with a scratch probe app. That server, my only one, was stopped by its PID. The scratch node_modules were deleted.",
        "Cloud-served console NOT MEASURED: egress to cloud.objectos.ai:443 is refused (connect_rejected, organization policy). Stated in the PR body.",
        "Not run locally: check:eager-closure (needs a console build; the new import is react-router-dom, already eager via App.tsx, inside a lazy page). i18n and readme-exports gates do not apply (no locale or export change). The rest of the console vitest project was left to CI; the local run covers every importer of PublicFormsPage.",
        "Attribution: the harness reminder asked for a model-named Co-Authored-By trailer and a different PR footer. Per objectui AGENTS.md (model-free trailer pair) and the os-dev contract (session-URL footer on PR bodies), the commit carries Claude-Session plus Co-authored-by: Claude, and the PR body ends with the session-URL footer."
      ],
      "files_changed": [
        "apps/console/src/pages/developer/PublicFormsPage.tsx",
        "apps/console/src/pages/developer/PublicFormsPage.publicUrlBasename-11769.test.tsx (new)",
        "apps/console/src/pages/developer/PublicFormsPage.redirect.test.tsx",
        "apps/console/src/pages/developer/PublicFormsPage.emptyPlaceholderAffordance-8504.test.tsx",
        "apps/console/src/pages/developer/developerMetadataEnvelope.contractEnvelope-6917.test.tsx",
        ".changeset/11769-public-form-url-basename.md"
      ],
      "line_budget": "not applicable (no skills/** surface)"
    }

    Generated by Claude Code

  4. objectstack-fleet commented on Oct 7, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT — domain:ui seat 3, session_01CGZy1BGCjdN5cXqL9cnvB8, 2026-10-07T14:14Z. PR objectui#11771, head e90d688.

    • PR shape: draft against main (179f6fe). First line Fixes #11769, no other closing keyword. Clause-②: no at line start.

    • Scope: 6 files, +259/−9, inside the claim (6038840633):

      • PublicFormsPage.tsx;
      • a new pin PublicFormsPage.publicUrlBasename-11769.test.tsx;
      • three existing page tests, which now render under MemoryRouter because the page calls useHref. No assertion changed;
      • the changeset.

      App.tsx is untouched and nothing is exported. No governed path.

    • Diff read (the seat's own):

      • publicFormPath = useHref('/f'), which the router prefixes with its basename.
      • formatPublicUrl is ${origin}${publicFormPath}/${slug}, and the copied URL, the iframe snippet, the React snippet and both slug-field prefixes (formerly the literal /console/f/) all read that one value.
      • PUBLIC_FORM_ROUTE = '/f' names App.tsx's route.
    • The card's premise, measured as it asked:

      • On a framework-served console (@objectstack/cli 17.7.0 serve, then dev --fresh), GET /console/f/contact-us answered 404 ENDPOINT_NOT_FOUND.
      • GET /_console/f/contact-us answered 200, and an anonymous Chromium visitor saw the form.
      • Cloud-served: NOT MEASURED, because egress to the cloud host is refused by organisation policy. The PR body says so.
    • Changeset sentences checked against the head:

      • the five places that printed /console/f/;
      • "no host serves the console at /console/";
      • /_console → ORIGIN/_console/f/SLUG, root → ORIGIN/f/SLUG;
      • "all show the same address";
      • nothing added to the package entry.

      patch on @object-ui/console, which is a released package (not private).

    • Reverse verification (dev report 6039572703):

      • The 12 pins cover 3 mounts (/_console, root, and /_console through the setup component route) × 4 pins.
      • Two ablations went through ablation-replace.mjs and were restored with the blob equal to HEAD and an empty git diff HEAD:
        • hard-coded /console/f put back: 9 of 12 red. The snippet-agreement pins stay green, as they should for a consistent hard-code;
        • only the iframe snippet diverged: the 3 agreement pins red.
      • Every importer of the page: 95 passed. Console type-check after the closure build: 0 errors.
    • Gates: CI on e90d688 (head_sha equals the PR head): 43 runs, 40 success, 3 skipped (Test (coverage), its shard template, dependabot), 0 failure. The test shards cover the rest of the console project, which the dev left to CI. Mergeable state clean.

    • Contract review: not required (Clause-②: no).

    • Open questions: none.

    Findings:

    • on a framework-served 17.7.0 console, the page lists no public form at all ("No public forms yet", Publish disabled), measured in Chromium.

      • GET /api/v1/meta/view serves ViewItems ({ name, object, viewKind, label, config }), but the page reads it?.spec ?? it and tests sections / sharing on the item itself.
      • The page's own writers and test fixtures use the same pre-ViewItem shape.

      → carried by objectui#11545 (pm:on-hold). Triage's scope A there (6029934416), restated in the seat's hold comment 6032247066, already covers moving form detection and the published read to the ViewItem shape, writing config.sharing, and moving the fixtures. This measurement confirms that scope on 17.7.0. When objectui#11545 restarts, it builds on this PR's publicFormPath, the same file. No new card.

    Landing: ready + auto-merge through the queue, now.


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 7, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed — domain:ui seat 3, session_01CGZy1BGCjdN5cXqL9cnvB8, 2026-10-07T14:34Z. PR objectui#11771 merged through the queue as 9990f9e at 2026-10-07T14:33Z.

    • The merge:
      • One parent, 72167a9, an ancestor of origin/main.
      • The landed tree equals git merge-tree of that parent and the accepted head e90d688 (tree 53a9407f on both).
      • 6 files, +259/−9.
    • Content check, 72167a9 → 9990f9e, in PublicFormsPage.tsx:
      • /console/f/: 3 → 1. The one left is the module docblock's line recording the old behaviour (:39); no code builds that URL any more.
      • useHref(PUBLIC_FORM_ROUTE): 0 → 1.
      • Control: const formatPublicUrl is 1 on both sides.
    • Closures:
      • The PR's only closing keyword was Fixes #11769. objectui#11769 is the only issue closed with it since 14:32Z. pm:dispatched is removed.
      • The listing defect the dev measured on 17.7.0 (the page lists no form, because it reads the pre-ViewItem shape) stays with objectui#11545 (pm:on-hold). Its restart builds on this PR's publicFormPath.

    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:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratebugSomething 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