Repository navigation
Commit b6eb25f
docs(spec): state the submitBehavior.url redirect contract without naming a navigation mechanism (#22714)
Fixes #22655
Clause-②: no
## What was false
`packages/spec/src/ui/view.zod.ts` ships in the npm tarball (`files[]`
carries `src/**/*.zod.ts`). Its docblock above the `submitBehavior.url`
check said two things that are false at the pinned Console:
- "objectui's `FormPage` performs a **verbatim redirect** on this value"
(present tense)
- "the value that reaches `window.location.assign` is this string with
its tokens substituted"
At `.objectui-sha` `20c6d351ad74d2b14a93becdc134d51b91b2d2e6`, read with
`git show SHA:PATH` in the objectui checkout:
- `apps/console/src/components/FormPage.tsx:2233` handles `case
'redirect'` by calling `resolveSubmitRedirect(behavior.url, …)` at
`:2248`. A refused url calls `toast.error(verdict.refusal)` and still
calls `setSubmitted(true)` (`:2264`–`:2266`).
- `apps/console/src/components/submitRedirect.ts:247` substitutes each
`{{record.field}}` token with
`encodeURIComponent(urlValue(record[field]))`.
- `FormPage.tsx:2143` calls `navigate(pendingRedirect)` from a
`setTimeout` of `redirectDelayMs`, where `redirectDelayMs` is
`behavior.delayMs ?? 0` (`:2140`) and `navigate` is React Router's
`useNavigate()` (`:1947`). The Console's redirect arm never calls
`window.location.assign`.
## Which sentences change, and which stay
The #7496 ruling (comment 5250627847) says, verbatim: "a verbatim
redirect on the resolved relative path IS the intended consumption."
That is point 3 of the contract. It names the destination, not a
navigation mechanism. Three readings agree:
- The card's "Done when" paraphrases it as "the resolved relative path
is the destination".
- The pinned Console's own `submitRedirect.ts` header restates it as
"the destination is that string with its tokens substituted, and nothing
else", and places point 3's consumption in that module.
- The hand-written `content/docs/ui/forms.mdx:368` (corrected in PR
#22651) keeps the sentence word for word and describes the Console's
mechanism in a separate paragraph.
So:
- **Changed (`view.zod.ts:4075`–`:4095`).** The present-tense `FormPage`
sentence is now marked as history: "History, as it stood when #7496 was
ruled: objectui's `FormPage` handed this value, as authored, to a
browser-level navigation …". This matches the pinned `FormPage.tsx`
header, which says the redirect "was consumed as a browser-level
navigation on the authored string". The `window.location.assign` clause
is gone. Point 3 now reads "the destination is this string with its
tokens substituted, and nothing else". A new sentence follows it: the
ruling fixes the destination, and the navigation mechanism belongs to
each consumer.
- **Unchanged.** The `url` `.describe()` (point 3, now `:4613`) and the
`submitBehavior` `.describe()`. Neither is false, so the generated
reference pages do not move, and `check:docs` stays clean (below).
- **Why the docblock names no mechanism instead of the current one.** At
the pin there are two consumers with two mechanisms. The Console's
`FormPage` navigates through React Router. `@object-ui/plugin-form`
(`ObjectForm`, `WizardForm`) uses a host-injected navigate when there is
one, and `window.location.assign` otherwise
(`packages/plugin-form/src/submitRedirectNavigation.ts:109` and `:112`).
Naming either would be true of only one consumer.
In `view-submit-redirect-url.test.ts`, the header's present-tense
"`FormPage` redirects **verbatim**" sentence gets the same correction.
Its list of ruled points keeps "verbatim redirect on the resolved path"
and adds the gloss "(the destination, not a navigation mechanism)". The
section heading, now `:247` ("Ruled bullet 3 — verbatim redirect on the
resolved relative path"), quotes the ruling's point 3 and already
matches the docblock, so it is unchanged. The comment at `:264` ("would
break `FormPage`'s read") is still true at the pin, because `FormPage`
hands `behavior.url` to `resolveSubmitRedirect(url: string, …)` as a
string. It is unchanged too.
There is no contract change: no executable line moved, so the accept set
of `submitBehavior.url` is the same.
## Changeset
`.changeset/22655-submit-redirect-docblock.md` is a `patch` for
`@objectstack/spec`. The edited `.zod.ts` is in the published tarball;
the test file is not.
## Verification
All readings were taken at HEAD `4dadbc180c`, on base `d8830c2805`.
- `pnpm --filter @objectstack/spec build`, run under `os-verify-lock`:
`VERDICT command-exit 0`, and `check-dts-emitted` reports 38/38.
- `pnpm --filter @objectstack/spec run check:docs`: exit 0, "✅ 225
generated files in sync with packages/spec".
- `pnpm --filter @objectstack/spec check:generated`: exit 0, "✓ All 15
generated artifacts are up to date".
- `pnpm check:spec-docblock-symbol-anchors`: exit 0, "5567 anchors
across 1970 spec sources resolve … 0 NEW line anchors on tracked targets
survive". Its present-tense report has 0 hits in either touched file.
- `vitest run src/ui/view-submit-redirect-url.test.ts`: 54 passed (54).
- `pnpm --filter @objectstack/spec exec vitest run --project local
--maxWorkers=2`: "Test Files 642 passed (642)" and "Tests 19164 passed |
1 todo (19165)".
- `pnpm --filter @objectstack/spec run typecheck`: exit 0 (tsc, the
scripts typecheck, and `check:test-typecheck` OK).
- `node scripts/pm/dispatch-gates.mjs --commands` derived 85 commands.
All 85 ran with exit 0, and `--ran` reconciles them as "85 derived, 85
run, 0 NOT-MEASURED, 0 UNRUN". They include:
- `check:nul-bytes`: 10706 files, no raw control bytes.
- `check:objectui-pin-citations`: 55 citations match `20c6d351a`.
- `check:doc-authoring`.
- `check:api-surface`: unchanged.
- The three changeset gates.
- `check:issue-citations`.
- `check:dts-closure`: 71 packages, 171/171 declaration files.
- `check:lean-entry-closure`, `check:dual-build-cjs-loads` and
`check:type-check-debt`: 1 ledger entry re-measured, none above its
recorded number.
There is no reverse verification or ablation, because the diff changes
no executable line and so there is no behaviour to revert.
## Acceptance notes
- `@object-ui/plugin-form` still falls back to `window.location.assign`
when a host injects no navigate. This is an objectui-side ruling
recorded in that file's header, not a defect. It is listed here only
because it is why the docblock names no mechanism. Carrier: none.
- The released `packages/spec/CHANGELOG.md` entry still says "the
renderer still redirects verbatim". That was true when the entry was
released, and release-owned text is not edited in a code PR.
- `origin/main` moved to `9f159397fb` after this branch was cut. `git
diff --stat HEAD...origin/main -- packages/spec content/docs/references`
is empty: nothing this diff touches or regenerates moved. The merge ref
is for CI to validate.
---
_Generated by [Claude
Code](https://claude.ai/code/session_016njDy8ozy9B9Ns5Y8kAWEK)_
Co-authored-by: Claude <noreply@anthropic.com>1 parent eae3368 commit b6eb25f
3 files changed
Lines changed: 34 additions & 10 deletions
File tree
- .changeset
- packages/spec/src/ui
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
9 | | - | |
| 9 | + | |
| 10 | + | |
10 | 11 | | |
11 | 12 | | |
12 | 13 | | |
13 | 14 | | |
14 | 15 | | |
15 | | - | |
16 | | - | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
17 | 19 | | |
18 | 20 | | |
19 | 21 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4072 | 4072 | | |
4073 | 4073 | | |
4074 | 4074 | | |
4075 | | - | |
4076 | | - | |
4077 | | - | |
4078 | | - | |
4079 | | - | |
| 4075 | + | |
| 4076 | + | |
| 4077 | + | |
| 4078 | + | |
| 4079 | + | |
| 4080 | + | |
| 4081 | + | |
4080 | 4082 | | |
4081 | 4083 | | |
4082 | 4084 | | |
| |||
4086 | 4088 | | |
4087 | 4089 | | |
4088 | 4090 | | |
4089 | | - | |
4090 | | - | |
| 4091 | + | |
| 4092 | + | |
| 4093 | + | |
| 4094 | + | |
| 4095 | + | |
4091 | 4096 | | |
4092 | 4097 | | |
4093 | 4098 | | |
| |||
0 commit comments