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
Console: an app opens on the first landing entry whose visible predicate holds #28450
Filing gate: ② the domain:ui half of a maintainer-ruled card: #28022, ruling 6545223246, letter A (maintainer 「同意」 2026-10-31T15:10Z), "spec first (this card, seat 2), then a domain:ui card for the redirect". The spec half is PR #28449. ⛔ Not a claim. Triage sets the grade.
Reach: any app shared by more than one audience. In HotCRM, moving Sales above Service moves service staff's landing to Leads (#27386 row 5).
Reader who acts: domain:ui. Lands after PR #28449 is on main.
Duplicate search: "app landing visible predicate console redirect" → #28022 (the spec half), #23610 (closed, wording). New.
AppSchema.landing is [{ item, visible }]: each entry names a navigation item, the first entry whose visible predicate holds is the landing, no match falls back to the first navigation item by order. A dangling item, a group / separator / action target and a data read are refused at parse (checkAppLandingItems).
Its liveness row is planned with an author warning: the console does not read the key yet, so an app still opens on its first navigation item.
Wanted
The console landing redirect (AppContent landing resolution) reads landing and evaluates each visible predicate in the same scope app navigation visible uses; first match wins; no match keeps today's rule. Decide and pin which roots the predicate may read (PR feat(spec): an app can name a landing per audience with landing #28449's acceptance note: no root verdict yet).
One-PR cross-domain exception, exactly the re-statements the card names: the liveness row app.landing flipped to live, and the dogfood cel-app-landing conformance row re-classified. Pin which roots the predicate may read in the same PR.
Blocked-by: #28449 is added to the body. pm:blocked.
Blocked-by: #28449, and PR feat(spec): an app can name a landing per audience with landing #28449 merged at 2026-10-31T19:30Z, so AppSchema.landing is on main. pm:blocked is removed. It stays at p3 without pm:queue. The one-PR exception (liveness row and dogfood conformance row) stands.
Claim: PM loop round 1 · 2026-10-31T22:58Z
Session: session_01L9qibw2uhdSeHYfnZdAf4V (seat; implementation by card thread session session_01L9qibw9TMGcWfAYsNMXXRo, mode:thread)
Account: os-tesla (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/project-thread-n3x42r
Worktree: objectstack-issue-28450
Domain: domain:ui
Seat: domain:ui#1
File surface: ui/packages/app-shell/src/console/**, ui/packages/types/** (the refinement + its test), packages/spec/liveness/app.json (row app.landing), packages/qa/dogfood/test/expression-conformance.ledger.ts (row cel-app-landing), tests, root changeset (stop on breach; explain in the report)
Container & model: M, mode:thread, model: default (dispatch-gates --tier: no path-derived mandate), effort: high
Clause-②: no (the console starts reading a key the spec already publishes; attaching checkAppLandingItems to objectui's AppComponentSchema would be a narrowing — the dev declares it from the diff and the seat runs the contract-tier review)
Metadata-protocol: semantic (measure from the diff; Skills-docs: line owed)
Responsibility: n/a — not a defect card
Thread-read: 6548383272
Premise: holds
Serial constraints cleared: PR #28477 (#27058, domain:ui#5/os-sales) edits ui/packages/app-shell/src/console/AppContent.tsx: ordinary concurrency, the later lander merges origin/main. No other live claim on this surface.
Order: /mnt/project-files/ui-seat-1/r2026-10-31b/dispatch-28450.md (pointer; the order rides the thread's opening message). Ruling: #28022 6545223246 letter A; triage 6547078750 (one-PR cross-domain exception).
Claim amendment 1 · 2026-10-31T23:10Z · amends claim 6550280340 at the card thread's request. Append-only.
Surface, added:packages/spec/src/ui/app.zod.ts, prose only: the landing member's .describe() drops its "[PLANNED — not yet rendered]" opener and the "No console reads this list yet …" sentence, and its JSDoc drops the "PLANNED: declared spec-first …" paragraph; plus the gen:schema / gen:docs regeneration that prose drives (content/docs/references/**). No schema shape changes.
Why in this PR: the same edit that flips the liveness row app.landing to live must not leave the published describe text saying the opposite; it is the describe-side twin of the liveness row the triage exception (6547078750) already puts in this PR.
Clause-② stays as claimed (no; (narrowing) if the AppComponentSchema attach lands). The spec text is published schema prose, so the seat's contract-tier review covers this file too.
Surface, added:content/docs/ui/apps.mdx: the landing row of the App properties table loses Planned., the warn Callout saying no console reads the key goes, and one line states the fault face (a faulting predicate passes its entry over). Docs travel with the surface they document (lanes/ui.md).
The PR body's line reads Skills-docs: updated here — content/docs/ui/apps.mdx (no skill teaches the key).
Claim amendment 3 · 2026-11-01T01:52Z · amends claim 6550280340 and amendments 6550410778, 6550418134, after contract review 6551992138 (FAIL on head 0ba3d126). Append-only.
Must-fix ④.1, surface added:packages/spec/src/ui/app.zod.ts takes url into LANDING_TARGET_REFUSED_TYPES and drops url from the refusal message's openable list; packages/spec/src/ui/app-landing.test.ts gains the url case; content/docs/ui/apps.mdx lists url among the refused targets. A url entry opens nothing inside the app, so the spec refuses it at landing.N.item instead of shipping an entry the console passes over in silence. The console's pass-over stays as defence.
Metadata-protocol:narrowed (was semantic): the spec's accept set for landing now refuses a url target. The changeset's @objectstack/spec entry carries the FROM → TO line (a url item → an in-app entry the app declares) and the ADR-0087 marker says so; minor on all three packages stands. Clause-②: no (narrowing) stands.
Should-fix, in this PR: ④.2 corrects navEntriesShownToMember's docblock (a doc landing opens the in-app docs portal under the server's audience gate) or passes the sidebar's doc check into the landing trees, the dev's choice, stated in the PR body; ④.3 one changeset line that AppComponentSchema now carries a refinement, so derive with .shape or .safeExtend().
Should-fix ④.4, out of this PR: the sidebar not following a landing into a second area is filed by the seat as its own domain:ui card; the PR body's acceptance note links it.
The amended head gets a fresh CONTRACT_REVIEW_TIER record before the seat's ACCEPT.
Claim amendment 4 · 2026-11-01T02:09Z · amends amendment 3 (6551999260) at the card thread's measured request. Append-only.
Surface, added:packages/spec/src/migrations/entries/semantic/18.app-landing-url-item-refused.ts, one SemanticMigration entry (surface, replacement, reason, acceptance criteria; no conversion).
Why:check-adr-0087-registration refuses not-required (no-migration-prescription) beside a changeset body that carries the FROM → TO prescription amendment 3 asks for (measured at 910aded5, evidence from-to-label), and its own fix is to register the migration. The changeset's marker becomes registered app-landing-url-item-refused. Not a governed path.
Landed · 2026-11-01T04:27Z · PR #28496 merged through the merge queue as 044d2016 at 2026-11-01T04:27:00Z, on the first pass. Records: contract FAIL 6551992138 (0ba3d126), PASS 6552593516 (65522b14), delta PASS 6552992988 and ACCEPT 6553190679 (both 531565de).
probe
before (044d2016~1)
now (origin/main)
resolveDeclaredLandingRoute in ui/packages/app-shell/src/console/AppContent.tsx
0
3
'action', 'url' (the refused landing targets) in packages/spec/src/ui/app.zod.ts
The card closed on Fixes; pm:dispatched comes off in the same stroke as this note. An app now opens on the first landing entry whose visible holds for the reader; a url landing target is refused at parse. The sidebar following a landing into a second area is #28497, claimed by this seat.
Activity
objectstack-fleet commentedon Oct 31, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: p3 ·
domain:ui·area:records·pm:blockedon #28449 · 2026-10-31T17:56Z⛔ Not a claim.
AppSchema.landing, ruled A on An app cannot give each audience its own landing page #28022 (「同意」). The parent An app cannot give each audience its own landing page #28022 is p3, so this card is p3 too.app.landingflipped to live, and the dogfoodcel-app-landingconformance row re-classified. Pin which roots the predicate may read in the same PR.Blocked-by: #28449is added to the body.pm:blocked.Generated by Claude Code
objectstack-fleet commentedon Oct 31, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: unblocked · p3 · 2026-10-31T19:55Z
⛔ Not a claim.
Blocked-by: #28449, and PR feat(spec): an app can name a landing per audience with landing #28449 merged at 2026-10-31T19:30Z, soAppSchema.landingis onmain.pm:blockedis removed. It stays at p3 withoutpm:queue. The one-PR exception (liveness row and dogfood conformance row) stands.Generated by Claude Code
objectstack-fleet commentedon Oct 31, 2026
domain:ui#1 · os-tesla · session_01L9qibw2uhdSeHYfnZdAf4V
Claim: PM loop round 1 · 2026-10-31T22:58Z
Session:
session_01L9qibw2uhdSeHYfnZdAf4V(seat; implementation by card thread sessionsession_01L9qibw9TMGcWfAYsNMXXRo,mode:thread)Account:
os-tesla(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/project-thread-n3x42rWorktree:
objectstack-issue-28450Domain:
domain:uiSeat:
domain:ui#1File surface:
ui/packages/app-shell/src/console/**,ui/packages/types/**(the refinement + its test),packages/spec/liveness/app.json(rowapp.landing),packages/qa/dogfood/test/expression-conformance.ledger.ts(rowcel-app-landing), tests, root changeset (stop on breach; explain in the report)Container & model:
M,mode:thread,model: default(dispatch-gates --tier: no path-derived mandate),effort: highClause-②: no (the console starts reading a key the spec already publishes; attaching
checkAppLandingItemsto objectui'sAppComponentSchemawould be a narrowing — the dev declares it from the diff and the seat runs the contract-tier review)Metadata-protocol: semantic (measure from the diff;
Skills-docs:line owed)Responsibility:
n/a — not a defect cardThread-read: 6548383272
Premise: holds
Serial constraints cleared: PR #28477 (#27058,
domain:ui#5/os-sales) editsui/packages/app-shell/src/console/AppContent.tsx: ordinary concurrency, the later lander mergesorigin/main. No other live claim on this surface.Order: /mnt/project-files/ui-seat-1/r2026-10-31b/dispatch-28450.md (pointer; the order rides the thread's opening message). Ruling: #28022 6545223246 letter A; triage 6547078750 (one-PR cross-domain exception).
objectstack-fleet commentedon Oct 31, 2026
domain:ui#1 · os-tesla · session_01L9qibw2uhdSeHYfnZdAf4V
Claim amendment 1 · 2026-10-31T23:10Z · amends claim 6550280340 at the card thread's request. Append-only.
packages/spec/src/ui/app.zod.ts, prose only: thelandingmember's.describe()drops its "[PLANNED — not yet rendered]" opener and the "No console reads this list yet …" sentence, and its JSDoc drops the "PLANNED: declared spec-first …" paragraph; plus thegen:schema/gen:docsregeneration that prose drives (content/docs/references/**). No schema shape changes.app.landingtolivemust not leave the published describe text saying the opposite; it is the describe-side twin of the liveness row the triage exception (6547078750) already puts in this PR.no;(narrowing)if theAppComponentSchemaattach lands). The spec text is published schema prose, so the seat's contract-tier review covers this file too.objectstack-fleet commentedon Oct 31, 2026
domain:ui#1 · os-tesla · session_01L9qibw2uhdSeHYfnZdAf4V
Claim amendment 2 · 2026-10-31T23:11Z · amends claim 6550280340 and amendment 6550410778. Append-only.
content/docs/ui/apps.mdx: thelandingrow of the App properties table loses Planned., the warn Callout saying no console reads the key goes, and one line states the fault face (a faulting predicate passes its entry over). Docs travel with the surface they document (lanes/ui.md).Skills-docs: updated here — content/docs/ui/apps.mdx(no skill teaches the key).objectstack-fleet commentedon Nov 1, 2026
domain:ui#1 · os-tesla · session_01L9qibw9TMGcWfAYsNMXXRo
os-dev-report
{ "issue": 28450, "status": "done", "branch": "claude/project-thread-n3x42r", "pr": "https://github.com/objectstack-ai/objectstack/pull/28496", "session": "session_01L9qibw9TMGcWfAYsNMXXRo", "premise_still_valid": true, "summary": "AppRootLanding resolves the app root through resolveDeclaredLandingRoute (new appDeclaredLanding.ts): landing entries in order, each visible asked with useNavMemberGates' evaluateVisibility (the navigation scope: current_user + user/ctx.user/os.user aliases, features; no data); the first that holds opens its item when the member is shown it, a fault or an out-of-scope root passes the entry over (reported once, withholding), no match keeps findFirstRoute. AppComponentSchema chains checkAppLandingItems (census row attached). Liveness app.landing live (authorWarn dropped), dogfood cel-app-landing enforced/fail-soft-log; seat amendments A: spec landing describe/JSDoc prose + content/docs/ui/apps.mdx, reference docs regenerated. Merged origin/main (incl. PR 28477) cleanly.", "tests": "head 0ba3d126. AppContent.declaredLanding-28450.test.tsx 12/12; ablation (resolveDeclaredLandingRoute(app?.landing -> undefined, ablation-replace anchor 1->0, restored blob==HEAD): 10 failed | 2 passed (controls). spec-object-refinements-7715 41/41; ablation (.superRefine(checkAppLandingItems) removed): 3 failed | 38 passed. vitest packages/types packages/app-shell packages/layout packages/runner: 2456 files passed, 2 failed (imported-defaults-8317, app-actions-retired-7469: refinement not yet accounted) -> fixed in 0ba3d126, the 3 files 331/331. ui scripts/ 169 files 4901 tests passed. type-check @object-ui/types + @object-ui/app-shell exit 0.", "gates": "dispatch-gates --commands (post-merge tree): 106 families, each with stdin closed, exits on disk; all exit 0 (check:type-check-debt first exit 3 lock queue-timeout = NOT MEASURED, re-run under lock: exit 0). --ran reconciliation: 106 derived, 106 run, 0 NOT-MEASURED, 0 UNRUN. Re-run on 0ba3d126 after test-only commits: check:cross-package-test-inputs, check:test-source-alias, check:nul-bytes, check:issue-citations, check:doc-authoring, ui check:new-line-citations: exit 0. spec check:generated after --fix: 14/14 up to date. CI check-runs on PR: in_progress at report time.", "dogfood_battery": "0ba3d126 · os-verify-lock VERDICT command-exit 0 · Test Files 363 passed | 3 skipped (366) · Tests 2926 passed | 28 skipped (2954) · no failure", "line_budget": "549 insertions / 55 deletions vs origin/main merge base before the last two commits; 13 files at PR open + 2 types test files; under 3000", "files_changed": [ ".changeset/28450-app-landing-console.md", "content/docs/references/api/metadata.mdx", "content/docs/references/ui/app.mdx", "content/docs/ui/apps.mdx", "packages/qa/dogfood/test/expression-conformance.ledger.ts", "packages/spec/liveness/app.json", "packages/spec/liveness/state-counts/app.md", "packages/spec/src/ui/app.zod.ts", "ui/packages/app-shell/src/console/AppContent.tsx", "ui/packages/app-shell/src/console/appDeclaredLanding.ts", "ui/packages/app-shell/src/console/__tests__/AppContent.declaredLanding-28450.test.tsx", "ui/packages/types/src/zod/app.zod.ts", "ui/packages/types/src/__tests__/spec-object-refinements-7715.test.ts", "ui/packages/types/src/__tests__/imported-defaults-8317.test.ts", "ui/packages/types/src/__tests__/app-actions-retired-7469.test.ts" ], "deviations": [ "files beyond the Claim surface, by seat amendments 6550410778/6550418134: packages/spec/src/ui/app.zod.ts (prose only), content/docs/ui/apps.mdx, and the two generated reference docs", "two existing types tests edited (imported-defaults-8317 REFINEMENT_EXCEPTIONS row; app-actions-retired-7469 control rebuilt from shape because zod refuses .omit() on a refined object): mechanical, forced by the attach", "neighbour file touched: ui/packages/app-shell/src/console/AppContent.tsx (PR 28477, already on main, merged cleanly)", "worktree is ../objectstack-28450 on the harness branch (Claim names objectstack-issue-28450)" ], "mcp_calls": "3 — mcp__github__issue_read x3 (get, get_comments x2; reads only); 0 writes", "api_writes": "2 — relay pr_create (PR 28496, run 41261788314), scripts/pm/post-stamped.mjs os-dev-report comment on 28450", "open_questions": [], "out_of_scope_findings": [ "class: b · reach: spec refusal text of checkAppLandingItems names `url` among the entries that open something, while the console app-root redirect passes a url entry over · evidence: packages/spec/src/ui/app.zod.ts checkAppLandingItems message; appDeclaredLanding.ts routeOf empty for url · dedupe words: app landing url entry, landing item url, landing passed over · carrier: seat (noted in Acceptance notes, not filed)", "class: none · reach: n/a · sidebar does not elect the landed area when the landing item lives in areas[1+] (UnifiedSidebar activeAreaId from first visible area, not URL); same for any deep link today · carrier: seat (Acceptance notes)" ] }objectstack-fleet commentedon Nov 1, 2026
domain:ui#1 · os-tesla · session_01L9qibw2uhdSeHYfnZdAf4V
Claim amendment 3 · 2026-11-01T01:52Z · amends claim 6550280340 and amendments 6550410778, 6550418134, after contract review 6551992138 (FAIL on head
0ba3d126). Append-only.packages/spec/src/ui/app.zod.tstakesurlintoLANDING_TARGET_REFUSED_TYPESand dropsurlfrom the refusal message's openable list;packages/spec/src/ui/app-landing.test.tsgains theurlcase;content/docs/ui/apps.mdxlistsurlamong the refused targets. Aurlentry opens nothing inside the app, so the spec refuses it atlanding.N.iteminstead of shipping an entry the console passes over in silence. The console's pass-over stays as defence.narrowed(wassemantic): the spec's accept set forlandingnow refuses aurltarget. The changeset's@objectstack/specentry carries the FROM → TO line (aurlitem → an in-app entry the app declares) and the ADR-0087 marker says so;minoron all three packages stands.Clause-②: no (narrowing)stands.navEntriesShownToMember's docblock (adoclanding opens the in-app docs portal under the server's audience gate) or passes the sidebar's doc check into the landing trees, the dev's choice, stated in the PR body; ④.3 one changeset line thatAppComponentSchemanow carries a refinement, so derive with.shapeor.safeExtend().domain:uicard; the PR body's acceptance note links it.CONTRACT_REVIEW_TIERrecord before the seat's ACCEPT.objectstack-fleet commentedon Nov 1, 2026
domain:ui#1 · os-tesla · session_01L9qibw2uhdSeHYfnZdAf4V
Claim amendment 4 · 2026-11-01T02:09Z · amends amendment 3 (6551999260) at the card thread's measured request. Append-only.
packages/spec/src/migrations/entries/semantic/18.app-landing-url-item-refused.ts, oneSemanticMigrationentry (surface, replacement, reason, acceptance criteria; no conversion).check-adr-0087-registrationrefusesnot-required (no-migration-prescription)beside a changeset body that carries the FROM → TO prescription amendment 3 asks for (measured at910aded5, evidencefrom-to-label), and its own fix is to register the migration. The changeset's marker becomesregistered app-landing-url-item-refused. Not a governed path.objectstack-fleet commentedon Nov 1, 2026
domain:ui#1 · os-tesla · session_01L9qibw2uhdSeHYfnZdAf4V
Landed · 2026-11-01T04:27Z · PR #28496 merged through the merge queue as
044d2016at 2026-11-01T04:27:00Z, on the first pass. Records: contract FAIL 6551992138 (0ba3d126), PASS 6552593516 (65522b14), delta PASS 6552992988 and ACCEPT 6553190679 (both531565de).044d2016~1)origin/main)resolveDeclaredLandingRouteinui/packages/app-shell/src/console/AppContent.tsx'action', 'url'(the refused landing targets) inpackages/spec/src/ui/app.zod.tspackages/spec/src/migrations/entries/semantic/18.app-landing-url-item-refused.tsThe card closed on
Fixes;pm:dispatchedcomes off in the same stroke as this note. An app now opens on the firstlandingentry whosevisibleholds for the reader; aurllanding target is refused at parse. The sidebar following a landing into a second area is #28497, claimed by this seat.