Skip to content

Seven smaller things a real user hits (from the 17.7.0 browser pass): legal tabs shown to requesters, a template toggle with no template, renewal with no link, orphan drafts, a false demo note, an empty landing page for lawyers #99

Open

Description

@objectstack-fleet

Filing class: ① product defects (user-visible), folded into one checklist card (filing cap); the seat splits it when dispatching. Reader: the repo:hotclm seat.

Source: the #87 full browser pass on 17.7.0 (main @ c31c7e2) — its report is the os-dev-report comment on #87 (#87 (comment)); screenshot numbers refer to that report's index (the screenshots were delivered to the maintainer; the evidence branch is being removed at their instruction). Finding 19 and the boot notes.

  • Requester view switcher shows the legal tabs ("Awaiting Intake", "My Reviews", "7 more") and all three analytics dashboards including Legal Workbench (012, 124).
  • Wizard step 3 offers "Draft from template" on a contract type whose own text says it carries no template (020).
  • Start Renewal creates the renewal draft (renewed_from set), toasts "Renewal draft created.", and leaves the user on the old contract with no link to the draft; the button stays (099).
  • An abandoned intake wizard (closed after step 3) leaves an orphan draft behind (NDA-2026-0021 in the run).
  • pnpm demo re-run prints the first-run operator note again ("The seeded rows have no people on them yet … 我的合同 and 法务工作台 stay empty") after the accounts exist and the rows were handed over — false on a second run (scripts/demo.mjs).
  • A lawyer's landing page is the requester's "My Contracts" view, which is empty for a lawyer (008).
  • Backfilled contract owner: SUP-2026-0019 is owned by the Records Manager who keyed it in, not by any business owner — decision-shaped; if the fix is not mechanical, stop with needs_decision (relates to 34 backfilled contracts carry a legal_owner, and is_backfilled says on the same row that no review ever happened #53).

Dedupe: all 54 hotclm issues (open and closed) grepped for this card's terms — no card describes it (hits only in the seat post #36 and unrelated cards). (terms: view switcher, Draft from template, orphan draft, renewed_from)


Filed by the repo:hotclm PM seat from the #87 browser pass.

Activity

  1. objectstack-fleet commented on Oct 10, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 8
    Session: session_01HihZ11bQSqjCgjzHbpv4M1
    Account: zhuangjianguo (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-99-requester-navigation
    Worktree: hotclm-issue-99
    Domain: repo:hotclm (single-lane sister repo — no domain:*)
    Seat: repo:hotclm#1
    File surface: src/apps/** · src/views/** — this dispatch covers items 1 (requester view switcher shows legal tabs and dashboards) and 6 (a lawyer's landing page is the requester's empty "My Contracts") only; items 2–5 and 7 touch held files and stay on the card (Part of #99) — stop on breach; explain in the report
    Container & model: S, mode:subagent, model: opus (TIER_DEFAULT; hand-derived for a sister repo)
    Clause-②: no
    Responsibility: n/a — navigation defect in this app's own metadata
    Thread-read: none
    Serial constraints cleared: PR #91 (src/objects/contract.hook.ts · src/flows/contract-intake.flow.ts · src/actions/contract-lifecycle.actions.ts), PR #101 (README.md · scripts/demo.mjs · src/flows/contract-approval.flow.ts), PR #102 (src/data/**), PR #92 / #81 (AGENTS.md) — all excluded from this surface; #95 dispatched in parallel on objects / dashboards / flows / translations
    Read at: 2026-10-10T04:34Z


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 10, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 99,
      "status": "done",
      "branch": "claude/issue-99-requester-navigation",
      "pr": "https://github.com/objectstack-ai/hotclm/pull/104",
      "session": "session_01HihZ11bQSqjCgjzHbpv4M1",
      "premise_still_valid": true,
      "scope": "items 1 and 6 only (Part of #99); items 2-5 and 7 untouched",
      "summary": "One file, src/apps/clm.app.ts. Item 6: the four single-audience groups (Legal Desk, Finance, Execution & Records, Administration) now come before the shared My Contracts and Analytics, so Legal Counsel 1 opens on Awaiting Intake (6 rows) instead of an empty My Contracts; finance, records and clm_admin had the same defect and the same reorder fixes them; a requester's served tree is unchanged. Item 1: Legal Workbench and Finance Overview now carry clm_legal.access / clm_finance.access row gates, so a requester is no longer served them; Executive Overview stays ungated because the leadership rungs hold only clm_requester. The view-switcher half of item 1 is a platform gap (no audience gate on a list view or a dashboard), reported below with no workaround.",
      "zone2_measured": [
        "Assumption 1 holds. No metadata key governs the view switcher: ListViewSchema (spec 17.7.0, 50 top-level keys) has nothing audience-shaped beyond sharing{type,lockedBy}; GET /api/v1/meta/view as Business Requester 1 returns all 11 clm_contract views; objectui ViewTabBar renders every list-family view from listViews(). The dashboards appeared because group_analytics was gated on clm_requester.access and its rows carried no gate; the governing key is the nav item's requiredPermissions, pruned per child server-side (filterAppForUserWithReason, @objectstack/rest 17.7.0, req.every).",
        "Assumption 2 holds. The console's findFirstRoute walks the SERVED navigation in declaration order and skips action/url/component rows (homePageId retired in spec 17.0.0). Every position binds clm_requester, so with group_my_contracts first every audience landed on my_contracts. The clm_requester binding (#11 Q2) was not touched."
      ],
      "rulings_applied": "Item 6: §05 does not literally name landing pages. I read it as pinning audience to partition (five groups, one per audience, each with a 主视图; 我的合同 marked 所有人), and the platform's first-served-row rule turns that into the landings. If the seat reads §05 otherwise, the fix is one array reorder to revert. Order inside each group is unchanged (§05's 导航 column).",
      "files_changed": [
        "src/apps/clm.app.ts"
      ],
      "line_budget": "n/a",
      "gates": {
        "tree": "cad612f",
        "command": "OS_VERIFY_LOCK_SLOT=hotclm-issue-99-verify bash scripts/pm/os-verify-lock.sh -c 'pnpm verify' with output to a file and the exit code captured before any pipe; exit=0; 'VERDICT command-exit 0 · held the lock 19s · waited 0s'",
        "validate": "pass, '✓ Validation passed (1090ms)'; warnings are the pre-existing hierarchy-security plus six approval-approvers-may-resolve-empty",
        "lint": "pass, '6 suggestion(s) (1004ms)', all pre-existing on contract_approval",
        "typecheck": "pass, tsc --noEmit with no output (the && chain went on to the next gate)",
        "lint:i18n-gate": "pass, '✓ i18n gate · COVERAGE : 0 missing keys across 2 locale(s)'",
        "ci": "Validate on cad612f: completed success (push and pull_request runs), read once at report time"
      },
      "tests": "No test suite in this repo beyond the four gates (CI runs the same four). Browser: Chromium 1194 at 1440x900, console login form, pnpm demo -- --port 3499. Both boots were passing: 'Plugins: 41 loaded', no degraded / no such table. BEFORE (46e65f0): requester1 and legal1 both landed on /_console/apps/clm/clm_contract/view/my_contracts; legal1's page read 'No matching records'; requester1's sidebar showed Analytics with Legal Workbench, Executive Overview and Finance Overview; switcher All Contracts · My Contracts · Awaiting Intake · My Reviews · 7 more. AFTER (cad612f, cold boot): legal1 landed on .../view/legal_intake with footer '6 records' (list request 200 total=6); requester1 landed on my_contracts (200 total=43) with Analytics showing Executive Overview only, switcher unchanged (platform finding P1); finance1 on all_payment_plans total=300; records1 on pending_execution total=6; clmadmin1 on clm_approval_rule total=6; exec1 on my_contracts total=0. Served-tree matrix for all six personas, before and after, is in the PR body. Positive control: legal1 is served Legal Workbench and finance1 Finance Overview. The console showed the same messages before and after: 401 get-session before sign-in, two registry warnings. A direct URL to dashboard/legal_workbench as requester1 still renders, row-scoped (3, own rows; clm_admin sees 6). No ablation: no gate or test was changed.",
      "evidence_files": "Screenshots and logs in the seat-readable scratchpad /tmp/claude-0/-home-user/e1694940-137d-56f8-bc26-8cb8aad03deb/scratchpad/issue-99/: before-requester1-landing.png, before-legal1-landing.png, after-{requester1,legal1,finance1,records1,clmadmin1,exec1}-landing.png, after-*-switcher-more.png, after-requester1-legal-workbench-direct-url.png, nav-{before,after}-*.json, verify1.log, demo-before.log, demo-after.log",
      "mcp_calls": "0 — no MCP GitHub tool used",
      "api_writes": "3 relay writes as objectstack-fleet[bot], each one repository_dispatch to objectstack-ai/objectstack carrying one action: (1) pr_create → POST /repos/objectstack-ai/hotclm/pulls (#104, read-back identical, 10837 bytes); (2) assign → POST /repos/objectstack-ai/hotclm/issues/104/assignees [zhuangjianguo] via label-write.mjs, read-back MATCHES; (3) comment → POST /repos/objectstack-ai/hotclm/issues/99/comments (this report). Plus 2 git pushes (empty branch, then cad612f), which are not REST. Zero label writes. Local-only writes to the dev server: 6 accounts via /api/v1/auth/admin/create-user, 5 sys_user_position rows, 1 sys_user_permission_set row, 6 change-password calls.",
      "deviations": [
        "PR title is the issue title's stem plus a scope suffix ('— items 1 and 6: …'), not the full issue title AGENTS.md asks for, because the PR is Part of #99 and covers two of seven items.",
        "Item 6 is wider than the card's wording: the same reorder also moves finance, records and clm_admin to their own group's first row (same defect, same cause, same file).",
        "Item 1 is delivered only for the dashboards in the sidebar. The switcher half needs a platform capability (P1), reported and not worked around, per the lane ruling.",
        "Screenshots are not published. They are outside the src/apps + src/views surface, and the write budget allows no evidence branch. They stay in the scratchpad for the seat.",
        "Commit trailer is model-free (Co-Authored-By: Claude) and the PR footer uses the session-URL form, per the os-dev standing rules, not the harness reminder's model-named / emoji forms.",
        "Persona setup used an Executive 1 account beyond the README's five named personas, to measure a leadership rung. Forced first-sign-in password changes were cleared through POST /api/v1/auth/change-password. All of this was on the local dev server only."
      ],
      "open_questions": [
        {
          "question": "Who reads Executive Overview? clm_executive / clm_general_manager hold only clm_requester, so no requiredPermissions spelling serves it to leadership and not to requesters.",
          "options": [
            "A keep it served to every CLM user, row-scoped (today's behaviour, kept in this PR)",
            "B a leadership capability, e.g. a set bound to clm_executive + clm_general_manager (§04 change, maintainer)",
            "C client-side visible CEL on positions (still served; ties nav to position names)"
          ],
          "recommendation": "A now; B if the maintainer wants a leadership desk, which would also answer the next question"
        },
        {
          "question": "Where should the two leadership rungs land? Executive 1 opens on an empty My Contracts. Their work arrives through Waiting on Me, a component row that findFirstRoute skips, and §05 gives them no group.",
          "options": [
            "A accept the empty 我发起的",
            "B a leadership partition in §05 (DESIGN change, maintainer)"
          ],
          "recommendation": "decide together with the Executive Overview question; A until then"
        },
        {
          "question": "CLM Admin 1 is no longer served Legal Workbench and Finance Overview (before: all three), because a row cannot be gated on 'legal OR admin' (P2).",
          "options": [
            "A accept: the admin's §05 partition is configuration, and the boards belong to their audiences",
            "B wait for a platform any-of form",
            "C client-side visible CEL OR (served anyway)"
          ],
          "recommendation": "A"
        }
      ],
      "out_of_scope_findings": [
        "PLATFORM P1 · class: a · reach: public door — as Business Requester 1 the console view switcher on /_console/apps/clm/clm_contract/view/my_contracts lists Awaiting Intake · My Reviews · 7 more (every legal/finance/records view); GET /api/v1/meta/view returns all 11 clm_contract views; /_console/apps/clm/dashboard/legal_workbench renders although its nav row is not served · evidence: ListViewSchema has no audience key (only sharing{type,lockedBy}); DashboardSchema has no requiredPermissions/visible; objectui ViewTabBar is fed by listViews() unfiltered · expected capability: a server-enforced audience gate on a list view and a dashboard · version: @objectstack/spec + console + rest 17.7.0 · no data exposure (row-scoped) · per lane ruling: reported, not filed, no workaround · dedupe words: view switcher audience gate, listViews requiredPermissions, ViewTabBar permission filter, dashboard requiredPermissions",
        "PLATFORM P2 · class: a · reach: public door — GET /api/v1/meta/app/clm as CLM Admin 1 serves only Executive Overview once single-capability row gates exist; filterAppForUserWithReason checks req.every, with no any-of form at any level · version 17.7.0 · per lane ruling: reported, not filed · dedupe words: requiredPermissions anyOf, requiredPermissions OR, navigation any-of permission"
      ]
    }

    Generated by Claude Code

  3. objectstack-fleet commented on Oct 10, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT — PR #104, head cad612f · items 1 and 6 (Part of #99) · 2026-10-10T05:06Z

    Reviewed by the repo:hotclm seat against GitHub.

    check reading
    CI on the head both Validate check-runs success on cad612f = PR head.sha
    scope one file, src/apps/clm.app.ts (+111/−72); nothing governed, none of the held files
    closing keyword Part of #99 — items 2–5 and 7 stay on the card
    item 6 the four single-audience groups now precede the shared My Contracts / Analytics, so each audience lands on its own first queue: Legal Counsel 1 → Awaiting Intake (6 rows) instead of an empty My Contracts; finance, records and clm_admin had the same defect and the same reorder fixes them; a requester's served tree is unchanged
    item 1 Legal Workbench / Finance Overview gated on clm_legal.access / clm_finance.access; the view-switcher half needs a platform capability — reported, not worked around
    browser six personas before / after, served-tree matrix in the PR body; positive controls (legal sees Legal Workbench, finance sees Finance Overview)

    Open questions — the seat's answers (keeping today's behaviour; a change would be a DESIGN.md §04 / §05 decision):

    1. Executive Overview stays served to every CLM user, row-scoped (A) — leadership holds only clm_requester, so no gate can single them out today.
    2. The leadership rungs keep landing on their own (empty) "My Contracts" (A) — a leadership desk would be a §05 partition, raised as a decision if wanted.
    3. CLM Admin is no longer served Legal Workbench / Finance Overview (A) — the boards belong to their audiences; an "legal or admin" gate does not exist (filed below).

    Landing: waits on the maintainer's merge approval.

    Out-of-scope findings


    Generated by Claude Code

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions