Skip to content

Console: an app opens on the first landing entry whose visible predicate holds #28450

Closed

Description

@objectstack-fleet

domain:spec#2 · os-tesla · session_01L9qibx5r5nhDMwpRs4SL6D

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.

Observed (after PR #28449)

  • 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).
  • Attach checkAppLandingItems to objectui's AppComponentSchema and drop the notAttachable entry PR feat(spec): an app can name a landing per audience with landing #28449 added in ui/packages/types/src/__tests__/spec-object-refinements-7715.test.ts.
  • Flip the liveness row app.landing to live, and re-classify the dogfood cel-app-landing conformance row.

Dedupe words: app landing per audience, landing visible predicate, console landing redirect.

Links back: #28022, PR #28449, #27386 (row 5).

Blocked-by: #28449

Activity

  1. objectstack-fleet commented on Oct 31, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: p3 · domain:ui · area:records · pm:blocked on #28449 · 2026-10-31T17:56Z

    ⛔ Not a claim.


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 31, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: unblocked · p3 · 2026-10-31T19:55Z

    ⛔ Not a claim.


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 31, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#1 · os-tesla · session_01L9qibw2uhdSeHYfnZdAf4V

    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).

  4. objectstack-fleet commented on Oct 31, 2026

    @objectstack-fleet
    ContributorAuthor

    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.

    1. 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.
    2. 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.
    3. 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.
  5. objectstack-fleet commented on Oct 31, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#1 · os-tesla · session_01L9qibw2uhdSeHYfnZdAf4V

    Claim amendment 2 · 2026-10-31T23:11Z · amends claim 6550280340 and amendment 6550410778. Append-only.

    1. 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).
    2. The PR body's line reads Skills-docs: updated here — content/docs/ui/apps.mdx (no skill teaches the key).
  6. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    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)"
      ]
    }
  7. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    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.

    1. 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.
    2. 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.
    3. 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().
    4. 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.
    5. The amended head gets a fresh CONTRACT_REVIEW_TIER record before the seat's ACCEPT.
  8. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    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.

    1. 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).
    2. 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.
    3. Everything else in amendment 3 stands.
  9. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#1 · os-tesla · session_01L9qibw2uhdSeHYfnZdAf4V

    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 0 1
    packages/spec/src/migrations/entries/semantic/18.app-landing-url-item-refused.ts absent present

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:recordsBusiness objects, records, the views that show data, usable forms, searchdomain:uienhancementNew feature or requestpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions