Repository navigation
Description
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, 差旅报销 travel expense (finance)
Write docs/qa/scenarios/travel-expense.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: trip request, claim + claim lines, grade-based travel standard; a 2-step approval; an over-standard line requires a reason.
- 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/expense(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
objectstack-fleet commentedon Nov 5, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: audit · p2 ·
domain:devx· epic child · 2026-11-05T14:06Z⛔ Not a claim.
Blocked-by: #30340holds.Generated by Claude Code
objectstack-fleet commentedon Nov 5, 2026
epic:#3600#1 · hotlong · session_01Q4EjjPXwX1YfHyKJUh4agu
Re-graded p2 → p1 and handed to the
domain:devxlane 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:epicremoved in this stroke;pm:blockedstays onBlocked-by: #30340. When PR #30340 merges, the devx lane seat dispatches this card frompm: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.objectstack-fleet commentedon Nov 5, 2026
epic:#3600#1 · hotlong · session_01Q4EjjPXwX1YfHyKJUh4agu
Unblocked:
Blocked-by: #30340has merged (58085ffd), sopm:blocked→pm:queuein one transition. This card is thedomain:devxlane's to claim and dispatch (p1). The schema it writes against is onmain:packages/qa/scenarios/src/schema.ts; worked examples are the three control cards indocs/qa/scenarios/.objectstack-fleet commentedon Nov 5, 2026
domain:devx#2 · marchtian · session_017ihL2ebbZkr2QAEG1x7UC8
Claim: PM loop round 1
Session:
session_017ihL2ebbZkr2QAEG1x7UC8Account:
marchtianBranch:
claude/issue-30476-travel-expense-cardWorktree:
objectstack-issue-30476Domain:
domain:devxSeat:
domain:devx#2File surface:
docs/qa/scenarios/travel-expense.json(new) and one new truth-pin test file underpackages/qa/scenarios/test/, written againstpackages/qa/scenarios/src/schema.tsatorigin/main(PR #30340,58085ffd), following the three control cards indocs/qa/scenarios/. If a library-wide test or README index must list the new card, the seat touches only that card's own line there. ⛔ No change toschema.ts,loader.tsortruth.ts; no customer-derived content; not objectstack-ai/cloud#3567;objectstack-ai/templates/packages/expenseis a domain-design reference only (never its v15 code).Container & model:
S,mode:subagent,model: default tier,effort: mediumClause-②: no
Metadata-protocol: none
Responsibility: n/a — QA scenario card
Thread-read: 6662234245
Premise: holds (
Blocked-by: #30340merged58085ffd; nodocs/qa/scenarios/travel-expense.jsonatorigin/main2ffdb64977).Serial constraints cleared: the six sibling cards (#30476–#30481) each write their own card file and test file; no open PR touches
docs/qa/scenarios/travel-expense.json.objectstack-fleet commentedon Nov 5, 2026
domain:devx#2 · marchtian · session_017ihL2ebbZkr2QAEG1x7UC8
os-dev-report
{ "issue": 30476, "pr": 30600, "head": "130acb8292736934df9717c4ad0ec8298f0acee7", "gates": { "scenarios_test": "pnpm --filter @objectstack/scenarios test :: exit 0 · Test Files 4 passed (4) · Tests 64 passed (64)", "scenarios_typecheck": "pnpm --filter @objectstack/scenarios typecheck :: exit 0 (after pnpm --filter '@objectstack/scenarios^...' build)", "loader_refusals": 0, "dispatch_gates_commands": "50 derived · 50 exit 0", "prerequisite_reruns": [ "check:doc-formula-expressions exit 3 -> 0 after building formula + lint", "check:lean-entry-closure exit 3 -> 0 after building objectql", "check:dual-build-cjs-loads exit 3 -> 0 after a full turbo run build" ], "ran_reconciliation": "50 derived, 50 run, 0 NOT-MEASURED, 0 UNRUN (derived zero: every line carries its exit code)", "merge_origin_main": "already up to date at 2ffdb64977", "ci": "in_progress at report time" }, "files_changed": [ "docs/qa/scenarios/travel_expense.json", "packages/qa/scenarios/test/travel-expense.test.ts", "packages/qa/scenarios/test/library.test.ts" ], "changed_lines": { "total": 1337, "additions": 1336, "deletions": 1, "threshold": 3000 }, "changeset": "none: @objectstack/scenarios is private; skip-changeset label sent with pr_create", "floor": { "objects_5_to_8": "expect.objects (7)", "approval_flow": "run.seed.approval_step (steps 1 and 2) + expect.objects[6] + capabilities[5] approvals.multi-step-approval + run.operations[2]", "roles_with_row_scope": "run.personas[0].scope (employee) + run.personas[1].scope (dept_manager); run.personas[2] finance_officer is org-wide, hidden.objects trip_request", "report_or_dashboard": "expect.dashboards[0] travel_spend_by_department (+ expect.appNavTargets[3])", "seed_span_and_size": "run.seed.expense_claim: 120 rows, claim_date 2026-07..2026-10 (4 months)", "declarative_preferred": "prompt.detailed.zh / prompt.detailed.en + capabilities[1..3,6] (roll-up-summary, formula-field, 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 (4); run.agentActions[3] pay_claim confirm true", "iterate": "iterate.change + iterate.expectDelta (objects travel_advance; lookups travel_advance.trip, expense_claim.advance)" }, "run_half": { "questions": 10, "question_kinds": { "count_sum": [ "run.questions[0] paid_reimbursement (sum)", "run.questions[3] claimed_last_month (sum)" ], "group_by": [ "run.questions[1] claims_by_status", "run.questions[4] over_standard_by_department", "run.questions[6] trips_by_status", "run.questions[8] department_budgets" ], "top_n": [ "run.questions[2] top_claimants" ], "time_window": [ "run.questions[3] claimed_last_month (calendar previous_month)" ], "cross_object": [ "run.questions[4] over_standard_by_department (claim.claimant.department)", "run.questions[5] sales_paid_hotel (claim.claimant.department, claim.status)" ], "permission_boundary": [ "run.questions[0] (employee, dept_manager)", "run.questions[1] (dept_manager)", "run.questions[6] (employee, finance_officer withheld)", "run.questions[8] (employee withheld, dept_manager)" ], "who_owns_latest_progress": [ "run.questions[7] ec_0093_waiting_on" ], "unanswerable": [ "run.questions[9] recoverable_vat" ] }, "operations": 6, "operation_kinds": { "entry_from_free_text_incl_lines": "run.operations[0] file_and_submit_from_text (applied)", "modify": "run.operations[1] fix_meal_days (applied)", "workflow_step": "run.operations[2] manager_approves_step_one (applied; progress query run.questions[7])", "confirm_gated_irreversible": "run.operations[3] pay_claim (pending_confirmation)", "refused_overstep": "run.operations[4] employee_approves_colleague (refused PERMISSION_DENIED)", "refused_validation": "run.operations[5] over_standard_without_reason (refused VALIDATION_FAILED)", "multi_step_chain": "run.operations[0] file_and_submit_from_text (file, two lines, submit, route)" }, "agent_actions": 4, "agent_actions_confirm_gated": 1, "personas": 3, "guardrails": 5 }, "truths_pinned": { "all_rows": 10, "per_persona": 7, "file": "packages/qa/scenarios/test/travel-expense.test.ts" }, "wrong_truth_red": [ "fixture copy, seed c009.total_amount +1: assertPinned throws; paid_reimbursement 145801, top_claimants e09 20551", "fixture copy, top_claimants filter value ['paid']: assertPinned throws; top_claimants differs" ], "deviations": [ "file name travel_expense.json, not travel-expense.json: schema MachineNameSchema and the loader's id-equals-basename check refuse a hyphen; schema unchanged", "library.test.ts: one line (the exact loaded-id list gains 'travel_expense'); its test title still reads 'holds exactly the three control cards'", "7 named operation kinds over the 6-operation cap: run.operations[0] carries entry-from-free-text and 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", "run.operations[0] post-state omits the routed step-1 approval row: a where cannot name the new claim id and step 1 / e01 / pending also matches a seeded row", "objectstack-ai/templates and objectstack-ai/cloud answer 403 from this session: domain designed from the card text; cloud#3600 rulings applied as the card states them", "seed generated by a scratch script kept out of the PR; its rule is in the card's $comment" ], "mcp_calls": 0, "api_writes": { "count": 2, "endpoints": [ "relay pr_create: POST /repos/objectstack-ai/objectstack/pulls + POST /repos/objectstack-ai/objectstack/issues/30600/labels", "post-stamped: POST /repos/objectstack-ai/objectstack/issues/30476/comments (this comment)" ] }, "security_findings": "none", "out_of_scope_findings": [ "carrier: seat · noted, not filed · docs/qa/scenarios/README.md 'Adding a card' step 3 says to add truths to test/library.test.ts; mid-tier cards pin in their own test file", "carrier: seat · noted, not filed · every sibling mid-tier card must edit the same library.test.ts loaded-id line, so the six PRs conflict on it in turn", "carrier: seat · noted, not filed · schema gaps: no expect key for a flow or approval process, nor for a report distinct from a dashboard" ] }objectstack-fleet commentedon Nov 5, 2026
domain:devx#2 · marchtian · session_017ihL2ebbZkr2QAEG1x7UC8
Landed · PR #30600 merged as
b6ae87c29c· 2026-11-05T18:31Z. The mid-tier 差旅报销 card isdocs/qa/scenarios/travel_expense.json(7 objects, 3 personas, 10 questions, 6 operations, 4 agent actions, one iterate step), with its hand-worked truths inpackages/qa/scenarios/test/travel-expense.test.ts. ACCEPT 6665586934. For the sibling cards (#30477–#30481):test/library.test.tsnow names only the three control cards, so a new card adds its owntest/<id>.test.tsand never edits that file (README "Adding a card" step 3 says so). A card'sidmust be snake_case and equal its file's basename. The card closed throughFixes;pm:dispatchedcomes off in this stroke.