Skip to content

Scenario library: mid-tier card — 采购申请到收货 requisition-to-receipt (8–10 问数 + 4–6 write operations, row-scoped personas) #30480

Closed

Description

@objectstack-fleet

epic:#3600#1 · hotlong · session_01Q4EjjPXwX1YfHyKJUh4agu

Filing-gate category: ④ in-scope child of #30289 (the scenario-library card schema). It is split out because the ruled scope measured over the 3000-line human-merge threshold: dev report comment 6658595859, seat decision on #30289. Maintainer rulings it carries are on objectstack-ai/cloud#3600: Q1 = v3 (comment 6658194654, 「同意这9个场景」), plus the execution parameter and declarative floor (comment 6658499884).

Blocked-by: #30340

Scope: one mid-tier scenario card, 采购申请到收货 requisition-to-receipt (procurement)

Write docs/qa/scenarios/requisition-to-receipt.json against the schema #30340 lands, plus its own truth-pin test file under packages/qa/scenarios/test/. A test file per card keeps the six card PRs from conflicting.

  • Domain: requisition, purchase order + lines, goods receipt, supplier; an amount-threshold multi-level approval.
  • Mid-tier floor:
    • 5–8 related objects;
    • ≥1 approval or automation flow;
    • 2–3 roles with row scope;
    • ≥1 report or dashboard;
    • seed spanning ≥3 months, ≥100 rows on the main object;
    • declarative preferred (flows, formulas, validation rules over code hooks), so a graduated app can install unmanaged.
  • Run half:
    • 8–10 read-only 问数 questions: count/sum, group-by, top-N, a time window, ≥2 cross-object, ≥2 permission-boundary (the truth differs per persona), "who owns / latest progress", ≥1 unanswerable-from-seed;
    • 4–6 write operations, each with its expected outcome declared: entry from free text incl. lines, a modify, a workflow step + progress query, a confirm-gated irreversible action, a refused overstep, a refused validation violation, one multi-step chain;
    • ≥3 agent-callable actions declared, ≥1 of them confirm-gated.
  • Iterate: one sentence, with its expected delta.
  • Reference: objectstack-ai/templates/packages/procurement (domain design only; ⛔ never its v15 code).
  • ⛔ No customer-derived content; ⛔ do not read or paraphrase objectstack-ai/cloud#3567.

Acceptance

  • The card loads with zero refusals. Every computed truth is asserted in the card's own test file against hand-worked values.
  • A deliberately wrong truth in a fixture copy goes red.
  • The PR stays under 3000 changed lines.

Reader: the epic PM of objectstack-ai/cloud#3600 dispatches it once PR #30340 merges. The six siblings are dispatched in parallel.


Generated by Claude Code

Activity

  1. added
    domain:devxDomain lane — seat card indexed by label:pm:seat
    pm:blockedBlocked by another issue/PR — body carries Blocked-by: #N
    pm:epicReserved by a dedicated epic PM, parent or sub-issue; other PMs never take it; never with pm:queue
    area:devpathThe road — create, dev, verify, publish/install, connect an agent, iterate
    on Nov 5, 2026
  2. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: audit · p2 · domain:devx · epic child · 2026-11-05T14:12Z

    ⛔ Not a claim.


    Generated by Claude Code

  3. added
    priority:p1High: required for production / M2
    and removed
    pm:epicReserved by a dedicated epic PM, parent or sub-issue; other PMs never take it; never with pm:queue
    on Nov 5, 2026
  4. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    epic:#3600#1 · hotlong · session_01Q4EjjPXwX1YfHyKJUh4agu

    Re-graded p2 → p1 and handed to the domain:devx lane on a maintainer ruling (Claude Code session 2026-11-05, recorded on objectstack-ai/cloud#3600), verbatim: 「都可以标记高优先级」, then on the seat's follow-up question the option 「p1 + 只交 6 张卡 (推荐)」. pm:epic removed in this stroke; pm:blocked stays on Blocked-by: #30340. When PR #30340 merges, the devx lane seat dispatches this card from pm:queue, overriding this body's "Reader" line. The card's body, and the rulings it cites, are the spec. Note for triage: this is a direct maintainer re-grade; NORTH-STAR's road-table rule yields to the ruling.

  5. added
    pm:queueReady for the PM dispatch loop
    and removed
    pm:blockedBlocked by another issue/PR — body carries Blocked-by: #N
    on Nov 5, 2026
  6. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    epic:#3600#1 · hotlong · session_01Q4EjjPXwX1YfHyKJUh4agu

    Unblocked: Blocked-by: #30340 has merged (58085ffd), so pm:blocked → pm:queue in one transition. This card is the domain:devx lane's to claim and dispatch (p1). The schema it writes against is on main: packages/qa/scenarios/src/schema.ts; worked examples are the three control cards in docs/qa/scenarios/.

  7. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 5, 2026
  8. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:devx#1 · os-elon-musk · session_016WV4cymvo9YoyLwKCXXBNw

    Claim: PM loop round 1
    Session: session_016WV4cymvo9YoyLwKCXXBNw
    Account: os-elon-musk
    Branch: claude/project-thread-rk7oyk (the card thread's platform-assigned branch; a measured platform exception to claude/issue-<n>-<slug>, runbook 〈卡线程〉) · card thread session session_016WV4cwyCQLVbmVSgGXVBhc
    Worktree: objectstack-issue-30480
    Domain: domain:devx
    Seat: domain:devx#1
    File surface: docs/qa/scenarios/requisition_to_receipt.json (new) and one new truth-pin test file packages/qa/scenarios/test/requisition-to-receipt.test.ts, written against packages/qa/scenarios/src/schema.ts at origin/main and following the control cards and docs/qa/scenarios/travel_expense.json (#30476, PR #30600). ⛔ No edit to test/library.test.ts (README "Adding a card" step 3), schema.ts, loader.ts or truth.ts. No customer-derived content; not objectstack-ai/cloud#3567; objectstack-ai/templates/packages/procurement is a domain-design reference only (never its v15 code).
    Container & model: p1 · M, mode:thread, model: default tier (dispatch-gates --tier --repo objectstack-ai/objectstack on the two paths: "no path-derived mandate"), effort: xhigh (p1)
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a — not a defect card
    Thread-read: 6662265484
    Premise: holds (Blocked-by: #30340 merged 58085ffd; no docs/qa/scenarios/requisition_to_receipt.json on origin/main b3d2f4bd; no open PR or remote branch for this card). Card body's kebab-case file name is corrected by the #30476 landing note 6665997189: a card id is snake_case and equals its file basename.
    Serial constraints cleared: siblings #30477 #30479 #30481 (domain:devx#3) and #30478/#30480 each write their own card file and test file; no open PR touches docs/qa/scenarios/requisition_to_receipt.json.

  9. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:devx#1 · os-elon-musk · session_016WV4cwyCQLVbmVSgGXVBhc
    os-dev-report

    {
     "issue": 30480,
     "status": "done",
     "branch": "claude/project-thread-rk7oyk",
     "pr": "https://github.com/objectstack-ai/objectstack/pull/30703",
     "head": "1590b31fb678c530102ec293c3bb7825aa945f81",
     "session": "session_016WV4cwyCQLVbmVSgGXVBhc",
     "premise_still_valid": true,
     "summary": "Adds the 采购申请到收货 requisition-to-receipt mid-tier card (8 objects; a 1 / 2 / 3-level approval set by amount at 5,000 and 30,000; personas requester and dept_manager row-scoped, buyer org-wide; 120 requisitions July-October 2026; 10 questions, 6 operations, 5 agent actions) and its own truth-pin test. Every truth was worked by hand from the $comment rule and the loader matched all 10 + 6 pins on the first run. No schema, loader, truth or library.test.ts edit.",
     "tests": "pnpm --filter @objectstack/scenarios test :: exit 0 · Test Files 5 passed (5) · Tests 69 passed (69) (head 1590b31fb6, after the main merge); pnpm --filter @objectstack/scenarios typecheck :: exit 0 (after pnpm --filter '@objectstack/scenarios^...' build); tsc --listFiles includes test/requisition-to-receipt.test.ts; eslint --no-inline-config on the new test file :: exit 0. Ablation: n/a, no runtime behaviour changed; the red direction is held by the two fixture-copy tests (wrong seed cell r062 +1 moves approved_spend to 1418401, requested_last_month to 493201 and both personas; top_suppliers filter ['received'] differs).",
     "gates": {
      "dispatch_gates_commands": "50 derived on head 1590b31fb6 · 50 exit 0",
      "ran_reconciliation": "50 derived, 50 run, 0 NOT-MEASURED, 0 UNRUN (derived zero: every line carries its exit code)",
      "first_sweep_on_3d37abf976": [
       "check-plugin-teardown-shape --self-test exit 3: shallow clone, pinned fixture unreachable; cleared by git fetch --unshallow origin main",
       "check:doc-formula-expressions exit 3, check:dual-build-cjs-loads exit 3: dist not built; cleared by a whole-tree turbo run build (119/119)",
       "check:dts-closure exit 1: ran while my objectql closure build was rebuilding @objectstack/metadata; exit 0 with no build running"
      ],
      "merge_origin_main": "merged b77c160a02 before pr_create (plain merge commit 1590b31fb6, clean); delta vs main still the 2 new files",
      "commit_trailers": "node scripts/check-commit-card-trailers.mjs --range origin/main..HEAD :: exit 0",
      "ci": "in_progress at report time; already success: Check Changeset, Check PR Size, Governed Surface Queue Guard, PR-body guards, Check Documentation Links, Test UI; UI build/type/lint lanes skipped by path filter"
     },
     "line_budget": {
      "total": 1332,
      "additions": 1332,
      "deletions": 0,
      "files": 2,
      "threshold": 3000,
      "verdict": "under"
     },
     "files_changed": [
      "docs/qa/scenarios/requisition_to_receipt.json",
      "packages/qa/scenarios/test/requisition-to-receipt.test.ts"
     ],
     "changeset": "none: @objectstack/scenarios is private; skip-changeset label sent with pr_create and read back on the PR",
     "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
     "floor": {
      "objects_5_to_8": "expect.objects (8)",
      "approval_flow": "run.seed.approval_step (levels 1, 2, 3) + expect.objects[4] + capabilities approvals.multi-step-approval, approvals.dynamic-approver-routing + run.operations[2]",
      "roles_with_row_scope": "run.personas[0] requester (e02) and run.personas[1] dept_manager (Sales, e13) scope all five transactional objects; run.personas[2] buyer is org-wide",
      "report_or_dashboard": "expect.dashboards[0] purchasing_spend_by_department (+ appNavTargets)",
      "seed_span_and_size": "run.seed.purchase_requisition: 120 rows, request_date 2026-07..2026-10",
      "declarative_preferred": "prompt.detailed zh/en + capabilities (formula-field, roll-up-summary, validation-rule, record-triggered-flow); no schema field grades it",
      "questions_8_to_10": "run.questions (10)",
      "operations_4_to_6": "run.operations (6)",
      "agent_actions_3_plus_1_confirm": "run.agentActions (5); cancel_purchase_order confirm true",
      "iterate": "supplier invoices with a three-way match: objects supplier_invoice; lookups supplier_invoice.purchase_order, supplier_invoice.supplier"
     },
     "run_half": {
      "count_sum": [
       "approved_spend (sum)",
       "requisitions_by_status (count)"
      ],
      "group_by": [
       "requisitions_by_status",
       "requisitions_by_approval_levels",
       "ordered_by_department",
       "department_budgets"
      ],
      "top_n": [
       "top_suppliers"
      ],
      "time_window": [
       "requested_last_month (calendar previous_month)"
      ],
      "cross_object": [
       "ordered_by_department (purchase_order.requisition.requester.department)",
       "laptops_received (po_line.item)"
      ],
      "permission_boundary": [
       "approved_spend (requester, dept_manager)",
       "requisitions_by_status (dept_manager)",
       "department_budgets (requester withheld, dept_manager, buyer withheld)"
      ],
      "who_owns_latest_progress": [
       "pr_0111_waiting_on"
      ],
      "unanswerable": [
       "laptops_in_stock"
      ],
      "operation_kinds": {
       "entry_from_free_text_incl_lines": "raise_po_from_text (applied)",
       "modify": "fix_chair_quantity (applied)",
       "workflow_step_plus_progress_query": "manager_approves_level_one (applied; ask includes the progress query; pr_0111_waiting_on is the pre-step answer)",
       "confirm_gated_irreversible": "cancel_sent_po (pending_confirmation)",
       "refused_overstep": "manager_approves_finance_level (refused PERMISSION_DENIED)",
       "refused_validation": "receive_more_than_ordered (refused VALIDATION_FAILED)",
       "multi_step_chain": "raise_po_from_text (order, two lines, send, requisition to ordered)"
      },
      "truths_pinned": {
       "all_rows": 10,
       "per_persona": 6
      }
     },
     "deviations": [
      "file name requisition_to_receipt.json, not the card body's requisition-to-receipt.json: id must be snake_case and equal the basename (landing note 6665997189); schema unchanged",
      "7 named operation kinds over the 6-operation cap: raise_po_from_text carries entry-from-free-text and the multi-step chain",
      "schema cannot express an approval flow, 'declarative preferred' or a report distinct from a dashboard as graded structure; stated in prompt + capabilities, as on travel_expense",
      "objectstack-ai/templates is outside this session's repository scope: domain designed from the card text alone",
      "seed generated by a scratch script kept out of the PR; its rule is the card's $comment; truths hand-derived (derivations beside the pins) and cross-checked by an independent count",
      "git fetch --unshallow origin main deepened the shared clone (one .git for every worktree) to reach a pinned self-test fixture",
      "the whole-tree turbo build held the shared verify lock 923 s (15m23s); the lock flags that as a possible holder-side finding, read here as the normal cost of that one command",
      "no subscribe_pr_activity, no PR assignee and no review request: os-dev.md rule 2 and its dispatch-contract-over-platform-posture clause; the seat sets those at hand-over",
      "the harness attribution reminder names the model in its Co-Authored-By line; commits carry the model-free pair per AGENTS.md (trailer checker exit 0)"
     ],
     "mcp_calls": "8 — all reads: issue_read get #30480, issue_read get_comments #30480 (x2), pull_request_read get #30600, issue_read get_comments #30476, issue_read get_labels #30703 (failed: a PR is not an issue there), pull_request_read get #30703, pull_request_read get_check_runs #30703; 0 write tools",
     "api_writes": {
      "count": 2,
      "endpoints": [
       "relay pr_create (run 42124010149): POST /repos/objectstack-ai/objectstack/pulls + POST /repos/objectstack-ai/objectstack/issues/30703/labels",
       "post-stamped: POST /repos/objectstack-ai/objectstack/issues/30480/comments (this comment)"
      ],
      "git_push": 2
     },
     "open_questions": [],
     "security_findings": "none",
     "out_of_scope_findings": []
    }
  10. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    epic:#3600#1 · hotlong · session_01Q4EjjPXwX1YfHyKJUh4agu

    Note for this card's author (domain:devx#1), from the epic PM's review of objectstack#30291 / PR #30594 (ruling D). The capability-tag table is closed: a tag with no check is reported unscored, never a pass. It now has 9 rows, listed in packages/qa/scenarios/README.md once PR #30594 merges:

    records-forms.lookup, records-forms.master-detail-inline-edit, records-forms.roll-up-summary, records-forms.select-options, access-security.field-permissions, access-security.row-scope, approvals.approval-flow, automation.record-triggered-flow, dashboards.widget-measures.

    The merged travel-expense card (#30476) declares 12 tags, and 7 of them score unscored: records-forms.formula-field, records-forms.validation-rule, approvals.multi-step-approval, access-security.row-level-security, dashboards.report, ai.ask-data, ai.agent-actions.

    Where a tag means the same as a row, use the row's name (e.g. access-security.row-scope, not access-security.row-level-security). Where it genuinely doesn't, keep it: an unscored tag is honest. The epic collects the demand and files one card to add checks for the most-used unscored tags once the six cards land.

  11. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:devx#1 · os-elon-musk · session_016WV4cymvo9YoyLwKCXXBNw

    Landed · PR #30703 merged as de6fbd4372 · 2026-11-05T23:59Z. The card closed through Fixes, and this stroke removes pm:dispatched.

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

Metadata

Metadata

Assignees

Labels

area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratedomain:devxDomain lane — seat card indexed by label:pm:seatpriority:p1High: required for production / M2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions