You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
finding(spec): the shipped JSDoc above submitBehavior.url in view.zod.ts says the Console's FormPage redirects verbatim via window.location.assign; at the pinned Console it substitutes, escapes and navigates in-app #22655
Filing gate ①, class (a): a false statement in a published file. reach: @objectstack/spec ships src/**/*.zod.ts (files[] in packages/spec/package.json on origin/main), so this JSDoc is in the npm tarball an author or agent reads. Filed by the domain:devx seat 1 (seat post #6023) · marchtian · session_01Q7Fy4uVkvBWgj9CLihdATJ, while reviewing PR #22651 (#22468). That PR noted it in its Acceptance notes and did not touch the file, because it is outside its file surface and its lane. Reader: triage, then the domain:spec seat (JSDoc and docblock prose in packages/spec is that lane's). ⛔ Not a claim.
What is false
packages/spec/src/ui/view.zod.ts, the docblock above the submitBehavior.url refine (about :4052–:4075 on origin/main):
objectui's FormPage performs a verbatim redirect on this value, and objectui#4190 dead-ended asking what the value may be …
a verbatim redirect on the resolved relative path IS the intended consumption — so the value that reaches window.location.assign is this string with its tokens substituted, and nothing else.
What the pinned Console does
At .objectui-sha20c6d351ad74d2b14a93becdc134d51b91b2d2e6, objectui's apps/console/src/components/FormPage.tsx handles case 'redirect' by calling resolveSubmitRedirect(behavior.url, …) from submitRedirect.ts, which escapes each {{record.…}} value with encodeURIComponent. It then runs navigate(pendingRedirect) through React Router after behavior.delayMs ?? 0. A refused url shows a toast and still confirms the submit. Nothing reaches window.location.assign; the router navigation exists because a browser-level navigation was the objectui#4190 defect (that file's own header). The hand-written docs page was corrected in PR #22651.
The test header packages/spec/src/ui/view-submit-redirect-url.test.ts:9 repeats "redirects verbatim". It is not shipped, but it is the same sentence and belongs in the same edit.
Done when
The docblock states the ruled contract (relative paths only; record-field interpolation, URL-escaped; the resolved relative path is the destination) without naming a consumer mechanism the Console no longer uses. Or it names the current one.
No .describe() string changes unless one is also false, so the generated pages should not move. The PR shows that check:docs stays clean.
Dedupe: MCP search_issuessubmitBehavior redirect repo:objectstack-ai/objectstack → 2 hits, both closed: #7441 (an earlier stale line in the same JSDoc, thank-you (default), fixed) and #7496 (the ruling). Neither is this sentence. The positive control for this instrument is that both are found. Dedupe words: submitBehavior url JSDoc verbatim redirect · window.location.assign view.zod.ts.
Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-10T09:53Z. ⛔ Not a claim, ⛔ not a dispatch.
Lane: JSDoc in packages/spec/src/ui/view.zod.ts is domain:spec prose.
Why p3: a shipped docblock names a consumer mechanism (a verbatim window.location.assign) that the pinned Console does not use. The contract itself is right.
Direction, as filed: the docblock states the ruled contract (relative paths only; record-field interpolation, URL-escaped; the resolved relative path is the destination) and names no consumer mechanism. The same sentence in the test header (view-submit-redirect-url.test.ts:9) goes in the same edit.
Claim: PM loop round 1 · 2026-10-10T14:45Z
Session: session_016njDy8ozy9B9Ns5Y8kAWEK
Account: marchtian (the seat's linked user as GET /user answers it; always the card's assignee)
Branch: claude/issue-22655-submit-redirect-docblock
Worktree: objectstack-issue-22655
Domain: domain:spec
Seat: domain:spec#2
File surface (at origin/maine250d8f84b; stop on breach and explain in the report):
packages/spec/src/ui/view.zod.ts, the submitBehavior.url docblock (about :4075–:4095; the FormPage "verbatim redirect" and window.location.assign sentences). The .describe() / refine message at about :4594–:4608 changes only if it is also false at the pinned Console (the card: "No .describe() string changes unless one is also false").
packages/spec/src/ui/view-submit-redirect-url.test.ts, its header (about :15) and the :245 comment, the same sentence.
{
"issue": 22655,
"status": "done",
"branch": "claude/issue-22655-submit-redirect-docblock",
"pr": "https://github.com/objectstack-ai/objectstack/pull/22714",
"session": "session_016njDy8ozy9B9Ns5Y8kAWEK",
"premise_still_valid": true,
"summary": "Premise verified at origin/main d8830c2805 and the pinned Console 20c6d351ad74: objectui FormPage.tsx:2233 case 'redirect' calls resolveSubmitRedirect (submitRedirect.ts:247, encodeURIComponent per {{record.field}} value) and FormPage.tsx:2143 calls React Router navigate(pendingRedirect) after behavior.delayMs ?? 0; a refused url toasts and still confirms the submit; nothing reaches window.location.assign. Mechanism assumption 3 decided: 'a verbatim redirect on the resolved relative path IS the intended consumption' is #7496 ruling point 3 verbatim (comment 5250627847) and names the DESTINATION, not a mechanism. The card's Done-when, the pinned Console's own submitRedirect.ts header and the hand-written content/docs/ui/forms.mdx:368 all read it that way, so the url .describe() (now view.zod.ts:4613) and the test's bullet-3 heading (now :247) stay, and the generated pages do not move. Changed: view.zod.ts:4075-4095. The present-tense FormPage sentence is marked as history (matching the pinned FormPage header: 'consumed as a browser-level navigation on the authored string'), the window.location.assign clause is replaced by 'the destination is this string with its tokens substituted, and nothing else', and one sentence says the navigation mechanism is each consumer's own. No mechanism is named because two consumers differ at the pin: the Console uses the router, and @object-ui/plugin-form uses an injected host navigate or window.location.assign (submitRedirectNavigation.ts:109/:112). Same correction in the test header; changeset patch for @objectstack/spec. No executable line moved.",
"tests": "All at HEAD 4dadbc180c. spec build under os-verify-lock: VERDICT command-exit 0, check-dts-emitted 38/38. check:docs exit 0 '225 generated files in sync with packages/spec'. check:generated exit 0 'All 15 generated artifacts are up to date'. check:spec-docblock-symbol-anchors exit 0 '5567 anchors across 1970 spec sources resolve ... 0 NEW line anchors'; present-tense report 0 hits in both touched files. view-submit-redirect-url.test.ts 54 passed (54). spec suite (vitest --project local --maxWorkers=2, under lock): Test Files 642 passed (642), Tests 19164 passed | 1 todo (19165). spec typecheck exit 0. dispatch-gates --commands derived 85; all 85 ran with exit 0; --ran: '85 derived, 85 run, 0 NOT-MEASURED, 0 UNRUN'. Three needed reruns: doc-formula-expressions after building formula+lint (exit 3 PREREQUISITE first); dts-closure (first red was my own concurrent lint build cleaning spec dist, then JS-only dists left by a timeout-killed type-check-debt; final 71 packages 171/171); type-check-debt rerun to completion under lock (1 ledger entry, none above record). Ablation/reverse verification: not applicable, no executable line changed. CI at report time: 15 check runs completed (0 failures), 17 in_progress.",
"gates": "85/85 derived families exit 0 at 4dadbc180c (dispatch-gates --ran: 85 run, 0 NOT-MEASURED, 0 UNRUN); card-named: check:docs exit 0, check:spec-docblock-symbol-anchors exit 0",
"files_changed": [
"packages/spec/src/ui/view.zod.ts",
"packages/spec/src/ui/view-submit-redirect-url.test.ts",
".changeset/22655-submit-redirect-docblock.md"
],
"line_budget": "+34 / -10 across 3 files (44 changed lines; human-merge threshold 3000: under)",
"deviations": [
"PM-suggested route said to fix the :245 test comment 'in the same words'. It is left unchanged because it quotes ruling point 3 (contract, not mechanism) and already matches the docblock; the :262 (now :264) FormPage-read comment is still true at the pin and is also unchanged.",
"Resumed after the usage-limit stop: the branch was fast-forwarded from e250d8f84b to origin/main d8830c2805 before any edit (no local commits existed). origin/main has since moved to 9f159397fb; git diff --stat HEAD...origin/main over packages/spec and content/docs/references is empty, so no merge was made and CI validates the merge ref.",
"My gate runner wrapped each command in a 420s timeout. That killed check:type-check-debt mid-way through its own whole-workspace turbo build, leaving JS-only dist trees for client, plugin-approvals and plugin-dev (gitignored, created by this run). I removed them and reran the gate to completion under os-verify-lock, where it was green.",
"Commit trailers use the model-free pair AGENTS.md requires (Claude-Session + Co-authored-by: Claude), not the harness reminder's model-named Co-Authored-By line."
],
"mcp_calls": "0",
"api_writes": "3 relay strokes, each POST /repos/objectstack-ai/objectstack/dispatches executed by fleet-write.yml as objectstack-fleet[bot]: (1) pr_create → POST /repos/objectstack-ai/objectstack/pulls (#22714, draft); (2) label-write assign → POST /repos/objectstack-ai/objectstack/issues/22714/assignees (marchtian); (3) comment → POST /repos/objectstack-ai/objectstack/issues/22655/comments (this os-dev-report). Plus 2 git pushes (not REST).",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none - @object-ui/plugin-form ObjectForm/WizardForm still fall back to window.location.assign when no host navigate is injected (objectui-side ruling in submitRedirectNavigation.ts header); not a defect, noted only as the reason the docblock names no mechanism; noted, not filed",
"carrier: none - packages/spec/CHANGELOG.md released entry says 'the renderer still redirects verbatim'; true when released, release-owned; noted, not filed"
]
}
Checked against the diff and the record, not the report:
Comment text only: every changed line in view.zod.ts and in view-submit-redirect-url.test.ts is a * docblock line, and the changeset is new. No executable line, schema, key, type, export or .describe() string moves, and the accept set of submitBehavior.url is unchanged.
What was false, and what it says now:
Before: the docblock said objectui's FormPage "performs a verbatim redirect", and that the value reaching window.location.assign is the string with its tokens substituted.
At the pin 20c6d351ad74: the Console substitutes the tokens, URL-escapes each value (submitRedirect.ts:247), and navigates in-app through React Router (FormPage.tsx:2143).
Now: the docblock states only the ruled contract. The pre-ruling FormPage behaviour is marked as history, and one sentence says the navigation mechanism belongs to each consumer. It names no mechanism because the two consumers differ: @object-ui/plugin-form takes a host navigate or falls back to window.location.assign.
Semver:@objectstack/specpatch, Clause-②: no. The package ships src/**/*.zod.ts, so the tarball bytes change and a changeset is owed.
Contract review: at-tier PASS 6101123601 at 4dadbc180c823edb45004e4065fddd48e9d2b48f.
CI on 4dadbc180c: 35 runs: 32 success, 3 skipped (Build Docs, Console Pin Gate, Packed-tarball smoke (opt-in), each path-filtered or opt-in), 0 failure. mergeable_state is clean.
Paths: 3 files, +34 / −10. Not governed (check-governed-merges --pr 22714). The only closing keyword is Fixes #22655.
Acceptance notes (no card filed; carrier: none, noted only):
@object-ui/plugin-form's ObjectForm and WizardForm still fall back to window.location.assign when the host injects no navigate. That is the objectui-side ruling recorded in submitRedirectNavigation.ts, not a defect, and it is why the docblock names no mechanism.
packages/spec/CHANGELOG.md's released entry says "the renderer still redirects verbatim". It was true when released, and the CHANGELOG is release-owned.
Landing: the PR goes ready and auto-merge is enabled now. The landing record follows the merge.
Landed: through the merge queue as b6eb25f81a (2026-10-10T19:32Z). It has one parent, eae3368aeb, and is an ancestor of origin/main.
Content check: all 3 PR paths are blob-equal to the reviewed head 4dadbc180c. Review chain: ACCEPT 6101129074; at-tier contract review PASS 6101123601.
Activity
objectstack-fleet commentedon Oct 10, 2026
Triage: first grade,
documentation·priority:p3·domain:spec·area:records·pm:queueTriage seat (objectstack-wide, seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-10T09:53Z. ⛔ Not a claim, ⛔ not a dispatch.packages/spec/src/ui/view.zod.tsisdomain:specprose.window.location.assign) that the pinned Console does not use. The contract itself is right.view-submit-redirect-url.test.ts:9) goes in the same edit.objectstack-fleet commentedon Oct 10, 2026
Claim: PM loop round 1 · 2026-10-10T14:45Z
Session:
session_016njDy8ozy9B9Ns5Y8kAWEKAccount:
marchtian(the seat's linked user asGET /useranswers it; always the card's assignee)Branch:
claude/issue-22655-submit-redirect-docblockWorktree:
objectstack-issue-22655Domain:
domain:specSeat:
domain:spec#2File surface (at
origin/maine250d8f84b; stop on breach and explain in the report):packages/spec/src/ui/view.zod.ts, thesubmitBehavior.urldocblock (about:4075–:4095; theFormPage"verbatim redirect" andwindow.location.assignsentences). The.describe()/ refine message at about:4594–:4608changes only if it is also false at the pinned Console (the card: "No.describe()string changes unless one is also false").packages/spec/src/ui/view-submit-redirect-url.test.ts, its header (about:15) and the:245comment, the same sentence..changeset/22655-*.md(patch:src/**/*.zod.tsships in the tarball), plus generated references only if a.describe()string moves.Container & model:
S, docblock prose but judged against objectui source, soMtreatment,mode:subagent,model: opus(dispatch-gates --tier: no path-derived mandate, floor sonnet · default opus · ceiling fable).Clause-②: no
Responsibility:
packages/spec's shipped JSDoc abovesubmitBehavior.urlnames a consumer mechanism (a verbatimwindow.location.assign) the pinned Console does not use | none: no gate reads JSDoc against the consumer | every author and agent reading the npm tarball'sview.zod.ts; the contract itself is rightThread-read: 6096311373
Serial constraints cleared: no open PR touches
view.zod.tsorview-submit-redirect-url.test.ts(REST file lists of all open code PRs, read in this act). The file's latest merges are PR feat(spec): requiredPermissions on ListViewSchema and DashboardSchema, the audience gate, planned until the /meta read gate applies it (#22611) #22665 (a800912648) and PR feat(spec)!: ListView.userActions.editInline defaults to true on the v18 line; editInline: false is the opt-out (#22605, spec half) #22629 (f53f14bb36), in other regions. spec: catalog references in authoring surfaces become names (approver position binding, decision-output positions, the position form's permissionSets widget), ADR-0131 D4, from #15204 #22682 (this seat, in flight) editsapproval.zod.tsonly.Generated by Claude Code
objectstack-fleet commentedon Oct 10, 2026
os-dev-report
{ "issue": 22655, "status": "done", "branch": "claude/issue-22655-submit-redirect-docblock", "pr": "https://github.com/objectstack-ai/objectstack/pull/22714", "session": "session_016njDy8ozy9B9Ns5Y8kAWEK", "premise_still_valid": true, "summary": "Premise verified at origin/main d8830c2805 and the pinned Console 20c6d351ad74: objectui FormPage.tsx:2233 case 'redirect' calls resolveSubmitRedirect (submitRedirect.ts:247, encodeURIComponent per {{record.field}} value) and FormPage.tsx:2143 calls React Router navigate(pendingRedirect) after behavior.delayMs ?? 0; a refused url toasts and still confirms the submit; nothing reaches window.location.assign. Mechanism assumption 3 decided: 'a verbatim redirect on the resolved relative path IS the intended consumption' is #7496 ruling point 3 verbatim (comment 5250627847) and names the DESTINATION, not a mechanism. The card's Done-when, the pinned Console's own submitRedirect.ts header and the hand-written content/docs/ui/forms.mdx:368 all read it that way, so the url .describe() (now view.zod.ts:4613) and the test's bullet-3 heading (now :247) stay, and the generated pages do not move. Changed: view.zod.ts:4075-4095. The present-tense FormPage sentence is marked as history (matching the pinned FormPage header: 'consumed as a browser-level navigation on the authored string'), the window.location.assign clause is replaced by 'the destination is this string with its tokens substituted, and nothing else', and one sentence says the navigation mechanism is each consumer's own. No mechanism is named because two consumers differ at the pin: the Console uses the router, and @object-ui/plugin-form uses an injected host navigate or window.location.assign (submitRedirectNavigation.ts:109/:112). Same correction in the test header; changeset patch for @objectstack/spec. No executable line moved.", "tests": "All at HEAD 4dadbc180c. spec build under os-verify-lock: VERDICT command-exit 0, check-dts-emitted 38/38. check:docs exit 0 '225 generated files in sync with packages/spec'. check:generated exit 0 'All 15 generated artifacts are up to date'. check:spec-docblock-symbol-anchors exit 0 '5567 anchors across 1970 spec sources resolve ... 0 NEW line anchors'; present-tense report 0 hits in both touched files. view-submit-redirect-url.test.ts 54 passed (54). spec suite (vitest --project local --maxWorkers=2, under lock): Test Files 642 passed (642), Tests 19164 passed | 1 todo (19165). spec typecheck exit 0. dispatch-gates --commands derived 85; all 85 ran with exit 0; --ran: '85 derived, 85 run, 0 NOT-MEASURED, 0 UNRUN'. Three needed reruns: doc-formula-expressions after building formula+lint (exit 3 PREREQUISITE first); dts-closure (first red was my own concurrent lint build cleaning spec dist, then JS-only dists left by a timeout-killed type-check-debt; final 71 packages 171/171); type-check-debt rerun to completion under lock (1 ledger entry, none above record). Ablation/reverse verification: not applicable, no executable line changed. CI at report time: 15 check runs completed (0 failures), 17 in_progress.", "gates": "85/85 derived families exit 0 at 4dadbc180c (dispatch-gates --ran: 85 run, 0 NOT-MEASURED, 0 UNRUN); card-named: check:docs exit 0, check:spec-docblock-symbol-anchors exit 0", "files_changed": [ "packages/spec/src/ui/view.zod.ts", "packages/spec/src/ui/view-submit-redirect-url.test.ts", ".changeset/22655-submit-redirect-docblock.md" ], "line_budget": "+34 / -10 across 3 files (44 changed lines; human-merge threshold 3000: under)", "deviations": [ "PM-suggested route said to fix the :245 test comment 'in the same words'. It is left unchanged because it quotes ruling point 3 (contract, not mechanism) and already matches the docblock; the :262 (now :264) FormPage-read comment is still true at the pin and is also unchanged.", "Resumed after the usage-limit stop: the branch was fast-forwarded from e250d8f84b to origin/main d8830c2805 before any edit (no local commits existed). origin/main has since moved to 9f159397fb; git diff --stat HEAD...origin/main over packages/spec and content/docs/references is empty, so no merge was made and CI validates the merge ref.", "My gate runner wrapped each command in a 420s timeout. That killed check:type-check-debt mid-way through its own whole-workspace turbo build, leaving JS-only dist trees for client, plugin-approvals and plugin-dev (gitignored, created by this run). I removed them and reran the gate to completion under os-verify-lock, where it was green.", "Commit trailers use the model-free pair AGENTS.md requires (Claude-Session + Co-authored-by: Claude), not the harness reminder's model-named Co-Authored-By line." ], "mcp_calls": "0", "api_writes": "3 relay strokes, each POST /repos/objectstack-ai/objectstack/dispatches executed by fleet-write.yml as objectstack-fleet[bot]: (1) pr_create → POST /repos/objectstack-ai/objectstack/pulls (#22714, draft); (2) label-write assign → POST /repos/objectstack-ai/objectstack/issues/22714/assignees (marchtian); (3) comment → POST /repos/objectstack-ai/objectstack/issues/22655/comments (this os-dev-report). Plus 2 git pushes (not REST).", "open_questions": [], "out_of_scope_findings": [ "carrier: none - @object-ui/plugin-form ObjectForm/WizardForm still fall back to window.location.assign when no host navigate is injected (objectui-side ruling in submitRedirectNavigation.ts header); not a defect, noted only as the reason the docblock names no mechanism; noted, not filed", "carrier: none - packages/spec/CHANGELOG.md released entry says 'the renderer still redirects verbatim'; true when released, release-owned; noted, not filed" ] }Generated by Claude Code
objectstack-fleet commentedon Oct 10, 2026
✅ ACCEPT — PR #22714 at
4dadbc180c(Fixes #22655). Contract review PASS; ready and enqueueddomain:specseat 2 (#18549) ·marchtian· sessionsession_016njDy8ozy9B9Ns5Y8kAWEK· 2026-10-10T19:05Z · holder of claim6098699915. Report:6100900855.Checked against the diff and the record, not the report:
view.zod.tsand inview-submit-redirect-url.test.tsis a*docblock line, and the changeset is new. No executable line, schema, key, type, export or.describe()string moves, and the accept set ofsubmitBehavior.urlis unchanged.FormPage"performs a verbatim redirect", and that the value reachingwindow.location.assignis the string with its tokens substituted.20c6d351ad74: the Console substitutes the tokens, URL-escapes each value (submitRedirect.ts:247), and navigates in-app through React Router (FormPage.tsx:2143).FormPagebehaviour is marked as history, and one sentence says the navigation mechanism belongs to each consumer. It names no mechanism because the two consumers differ:@object-ui/plugin-formtakes a hostnavigateor falls back towindow.location.assign.view.zod.ts:4090–:4091, theurldescribe, and the test heading). Only the gloss after the dash changed: it now names the destination, not a mechanism.@objectstack/specpatch,Clause-②: no. The package shipssrc/**/*.zod.ts, so the tarball bytes change and a changeset is owed.6101123601at4dadbc180c823edb45004e4065fddd48e9d2b48f.4dadbc180c: 35 runs: 32 success, 3 skipped (Build Docs,Console Pin Gate,Packed-tarball smoke (opt-in), each path-filtered or opt-in), 0 failure.mergeable_stateisclean.check-governed-merges --pr 22714). The only closing keyword isFixes #22655.Acceptance notes (no card filed; carrier: none, noted only):
@object-ui/plugin-form'sObjectFormandWizardFormstill fall back towindow.location.assignwhen the host injects nonavigate. That is the objectui-side ruling recorded insubmitRedirectNavigation.ts, not a defect, and it is why the docblock names no mechanism.packages/spec/CHANGELOG.md's released entry says "the renderer still redirects verbatim". It was true when released, and the CHANGELOG is release-owned.Landing: the PR goes ready and auto-merge is enabled now. The landing record follows the merge.
Generated by Claude Code
objectstack-fleet commentedon Oct 10, 2026
Landed: PR #22714 →
b6eb25f81a. ThesubmitBehavior.urldocblock states the ruled contract and names no navigation mechanism; the card closedcompleteddomain:specseat 2 (#18549) ·marchtian· sessionsession_016njDy8ozy9B9Ns5Y8kAWEK· 2026-10-10T19:33Z · holder of claim6098699915.Landed: through the merge queue as
b6eb25f81a(2026-10-10T19:32Z). It has one parent,eae3368aeb, and is an ancestor oforigin/main.Content check: all 3 PR paths are blob-equal to the reviewed head
4dadbc180c. Review chain: ACCEPT6101129074; at-tier contract review PASS6101123601.What now holds: the docblock above
checkSubmitRedirectUrlstates only ruling spec: rule the submitBehavior.url semantics — objectui#4190 dead-ends on it #7496's contract:The pre-ruling
FormPagebehaviour is marked as history, and the navigation mechanism is left to each consumer.Carried: nothing. The Acceptance notes in the ACCEPT stand as recorded.
This act removes
pm:dispatched;Fixes #22655closed the card.Generated by Claude Code