Repository navigation
Commit 36ac4b4
docs(forms): restate the redirect status note as what the pinned Console does (#22651)
Fixes #22468
Clause-②: no
## What changed
`content/docs/ui/forms.mdx`, section "What a `redirect` `url` may be",
two lines:
1. **The dated note is gone.** "Current renderer status (2026-08-11)"
said the Console redirects verbatim and does not substitute or escape
`{{record.…}}` tokens, and told authors to write a plain path. It is
replaced by one undated sentence saying what the Console does:
> The Console applies the three rules at submit time: it resolves each
`{{record.…}}` token from the record the submit just wrote, URL-escapes
the value, and navigates to the resolved path inside the console shell
after `delayMs`; a `url` the schema refuses is never followed — the
submit is still confirmed and the refusal is shown on screen.
2. **The `redirect` row of the "Renderer behavior" table on the same
page.** It said `window.location.assign(url)`, which is the same
out-of-date claim in another form: a full-page load of the raw `url`.
The Console moved away from that in the same objectui change. The row
now reads: "Navigate in-app to `url`, its `{{record.…}}` tokens
substituted and URL-escaped, after `delayMs` (defaults to 0) — see
below."
The section's three numbered rules and the "The default is mode-aware"
subsection are unchanged.
## Evidence: what the pinned Console does
The pin is `.objectui-sha` = `20c6d351ad74d2b14a93becdc134d51b91b2d2e6`.
It is the same on this branch's base `cc305a3cf` and on `origin/main`
`0ec426897`. I read it in objectui with `git show
20c6d351ad74d2b14a93becdc134d51b91b2d2e6:PATH`:
- `apps/console/src/components/submitRedirect.ts`,
`resolveSubmitRedirect(url, record)`:
- Rule 1: it calls `checkSubmitRedirectUrl`, which parses a minimal
`FormViewSchema` from `@objectstack/spec/ui`. If the schema refuses the
url, the function returns the spec's refusal message and does not
navigate.
- Rule 2: it replaces each `{{record.field_name}}` token with
`encodeURIComponent` of the field's scalar value. If a brace is still
left after that, the redirect is refused.
- Rule 3: the result is the resolved path.
- `apps/console/src/components/FormPage.tsx`, submit handler, `case
'redirect'`:
- It calls `resolveSubmitRedirect(behavior.url, …)`. The token scope is
the submitted payload, then the server's echoed record, then the written
id.
- On a refusal it calls `toast.error(refusal)`, keeps the refused state
on screen and calls `setSubmitted(true)`.
- On success it keeps the resolved path as pending. An effect then runs
`setTimeout(() => navigate(path), behavior.delayMs ?? 0)`, which is a
React Router navigation under the console basename, not
`window.location.assign`.
## Fixing the table row here as well
The four conditions for a bounded in-place fix all hold:
1. It is the same defect class as the card: a statement about how the
Console handles the redirect arm that is false at the pin.
2. The edit is mechanical, and its new wording is set by the measured
code above.
3. No other claim holds the file. The claim's serial-constraints line
read 13 open PRs and none touches it.
4. It adds no new verification surface: it is the same file and the same
docs gate family.
The file surface is unchanged: `content/docs/ui/forms.mdx` only.
## Grep: no other page restates the old status
The pattern is the old note's own phrases plus the old table spelling:
```
PAT='Current renderer status|does not yet substitute|reach the browser literally|write a plain path|objectui#4190|objectui/issues/4190|redirects (\*\*)?verbatim|window\.location\.assign'
git grep -n -i -E "$PAT" REF -- content/docs skills
```
| REF | exit | hits |
|---|---|---|
| `00c98860b` (this PR's head) | 1 | none |
| `cc305a3cf` (base, positive control) | 0 |
`content/docs/ui/forms.mdx:358` (the table row) and
`content/docs/ui/forms.mdx:385` (the note) |
The scope is the whole `content/docs` tree, including the generated
`references/`, plus the published `skills/`. Nothing under
`content/docs/references/**` or `content/docs/releases/**` matches, so
neither was edited. `references/ui/view.mdx:500` restates rule 3 only,
which is the contract and not a status.
The same pattern over the rest of the repo at head finds no hand-written
docs page. It finds these, none of them a page this card covers:
- `packages/spec/CHANGELOG.md:42202,42248-42249`: a released,
release-owned entry that was accurate when it shipped. Not edited.
- `packages/console/CHANGELOG.md:2251`: describes the objectui change
correctly.
- `packages/spec/src/ui/view.zod.ts:4058-4072` and
`packages/spec/src/ui/view-submit-redirect-url.test.ts:9`: code
comments. See Acceptance notes.
- `packages/client/src/index.ts:4752`: an unrelated auth redirect.
## Gates
Derived with `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` (no paths) at head `00c98860b`: 40 commands,
the same 40 the dispatch named.
- All 40 ran at `00c98860b` and exited 0.
- `pnpm --filter @objectstack/spec run check:skill-examples` first
exited 3 with PREREQUISITE NOT MET because `packages/client-react/dist`
had no `.d.ts`. That is not a measurement. I built
`@objectstack/client-react...` and `@objectstack/client...`, re-ran it,
and it exited 0: "262 prose examples type-check across 3 surface(s)".
- Before the spec and lint gates I built the `@objectstack/lint...`
closure, which includes spec, under `scripts/pm/os-verify-lock.sh`
(`VERDICT command-exit 0`).
- `--ran` reconciliation with the exit codes recorded: "40 derived, 40
run, 0 NOT-MEASURED, 0 UNRUN".
- Not run locally, as CI owns them: the whole-tree families, the Build
Docs job and the type-check lanes that the derivation lists outside its
40.
Docs only, nothing published: `skip-changeset`.
## Acceptance notes
These are not filed. They are comment drift, outside the three filing
classes, and nobody else is set to edit these files.
- `packages/spec/src/ui/view.zod.ts:4058-4072`: the JSDoc above the
`submitBehavior.url` refine still says objectui's `FormPage` "performs a
verbatim redirect" and that the resolved value "reaches
`window.location.assign`". At the pin, the Console navigates through the
router. This is a code comment, not `.describe()`, so it reaches no
generated page.
- `packages/spec/src/ui/view-submit-redirect-url.test.ts:9`: the test
header says the same "redirects verbatim". Same nature.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01Q7Fy4uVkvBWgj9CLihdATJ)_
Co-authored-by: Claude <noreply@anthropic.com>1 parent d817f18 commit 36ac4b4
1 file changed
Lines changed: 2 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
355 | 355 | | |
356 | 356 | | |
357 | 357 | | |
358 | | - | |
| 358 | + | |
359 | 359 | | |
360 | 360 | | |
361 | 361 | | |
| |||
382 | 382 | | |
383 | 383 | | |
384 | 384 | | |
385 | | - | |
| 385 | + | |
386 | 386 | | |
387 | 387 | | |
388 | 388 | | |
| |||
0 commit comments