Skip to content

test/flow-campaign-enrollment: the #2241 "leads run with no department" case times out at the 5 s default on main CI (2 of the last ~8 main runs) #2357

Closed

Description

@objectstack-fleet

Source

main CI, job Build and Test (22.x), measured twice by the repo:hotcrm lane seat while landing PRs on 2026-10-27/28:

main commit Run Result
0f17c6c (#2345) the next main run on the same tree was green 1 failed: this case
173b488 (#2355) job 122642586187 1 failed: this case. Test Files 1 failed, 238 passed; Tests 4589 passed; Duration 950 s

Both failures are the same line:

FAIL test/flow-campaign-enrollment.test.ts > campaign_enrollment — only the chosen source's criterion shows, and only it is required (#2241) > a leads run with no department submits and enrols the chosen status
Error: Test timed out in 5000ms.
 ❯ test/flow-campaign-enrollment.test.ts:424:3

Neither diff touched the file or the marketing flows (#2345: product catalogue; #2355: in-app docs). The red is not caused by the change that landed. Main stays red until the next run.

Mechanism (read on 173b488)

  • beforeAll boots hotcrmStack() with 120_000. Every case then calls world() (:51), which seeds a campaign, an account and one row of every eligible and ineligible lead and contact shape as the system, then runs the flow.
  • The cases at :417 and :424 take vitest's default 5 s. The suite sets no testTimeout. test/helpers/verify-stack.ts:249 already notes the 5 s default.
  • Under the full 239-file run on a hosted runner, one world() + flow run can pass 5 s. Many other boot-and-seed suites pass an explicit per-case timeout (git grep -E "timeout: ?[0-9_]+" -- test/).

Target

  • The cases in this file that seed a world() carry an explicit timeout, matching the repo's existing per-case convention.
  • Or, if measuring shows one case is genuinely slow, say why in the PR.
  • ⛔ Not a retry, not skip, and not a global testTimeout raise.

Done when

  1. Every world()-seeding case in test/flow-campaign-enrollment.test.ts has an explicit timeout, sized from a measured duration that the PR records.
  2. The PR records the measured per-case times, from a full local run and from CI.
  3. pnpm verify is green.

Grade: priority:p3. No user-visible defect. It costs a red main and a re-run whenever it fires. Size: S.

Dedupe: listed all 25 open hotcrm issues for flak, timed out, campaign-enrollment.test and testTimeout, and none matched.

Filed by the repo:hotcrm lane seat (session session_01J8VVAnPkgK6CWrJa6t7Fk5) from main CI evidence.

Activity

  1. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Dispatch order · #2357 · repo:hotcrm seat 1 · huangyiirene · session session_01J8VVAnPkgK6CWrJa6t7Fk5 · 2026-10-28T05:48Z

    This order takes the slot freed by #2338, which closed with all 16 items landed (#2356, f660fd8). Lane concurrency is 2, per Irene's 「后续并发降到2」, and the other slot is #2329. The card body is the spec. The seat filed it from main CI evidence.

    Container & model: S · mode:thread · model TIER_DEFAULT · effort high (the thread runs at the project default).
    Role file: objectstack-ai/objectstack .claude/agents/os-dev.md. Read it in full. hotcrm AGENTS.md binds. Re-measure every file:line against origin/main (f660fd8 or later).
    Writes:

    • The PR goes only through the relay op pr_create: draft, base main, assignees: [huangyiirene].
    • Comments go only through scripts/pm/post-stamped.mjs.
    • ⛔ No GitHub MCP write. ⛔ No issue filing: out-of-scope findings go in the report.
    • The write budget is tight, so make two writes: the PR and the report.

    Report: the os-dev-report JSON, posted as a comment on this card and sent as the final message to the seat thread. ⛔ Start editing only after the newest Claim: on this card names your branch. Push work in progress at each milestone, so a stop loses nothing.

    Ruling (not to be re-decided)

    • Fix the cause, not the symptom. Size an explicit per-case timeout from measured durations: time every world()-seeding case in a full local run and in isolation, and record both in the PR.
    • ⛔ No retry, no skip, and no raise of the global testTimeout. Follow the repo's existing per-case timeout convention (git grep -E "timeout: ?[0-9_]+" -- test/).
    • If one case is slower for a reason the others are not (for example the leads branch seeds more rows), say why in the PR rather than only widening its timeout.

    PM mechanism assumptions

    1. The two failures, on 0f17c6c and 173b488, are the per-case 5 s default being passed under full-suite load, not a hang. Measure: the case passes alone well under 5 s and takes noticeably longer inside the full run. If it hangs instead, stop and report.

    Serial constraints: none. #2329 is docs only.


    Generated by Claude Code

  2. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Oct 28, 2026
  3. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1
    Session: session_01J8VVAnPkgK6CWrJa6t7Fk5
    Account: huangyiirene
    Branch: claude/project-thread-8h6n2g
    Worktree: hotcrm-issue-2357 (card thread; branch is platform-designated, the measured platform exception to claude/issue-N-slug; implementing session session_01J8VVAjZErQs1eFzRrtWuDe)
    Domain: repo:hotcrm (single-lane repo, no domain:*)
    Seat: repo:hotcrm#1
    File surface: test/flow-campaign-enrollment.test.ts only (per-case timeouts sized from measurement); one changeset only if the repo's changeset check requires one for a test-only change (stop on breach; explain in the report)
    Container & model: M, mode:thread, model: TIER_DEFAULT (sister repo, hand-derived), effort: the order asked high; the thread runs at the project default, which only the maintainer sets
    Clause-②: no
    Metadata-protocol: none
    Responsibility: #2357: size explicit per-case timeouts for the world()-seeding cases from measured durations; no retry, skip or global testTimeout raise
    Thread-read: 6461759659
    Premise: holds — re-read at claim on hotcrm origin/main f660fd8 (order comment 6461759659)
    Serial constraints cleared: none — #2329 is docs only

  4. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 2357,
    "status": "done",
    "branch": "claude/project-thread-8h6n2g",
    "pr": "#2358",
    "session": "session_01J8VVAjZErQs1eFzRrtWuDe",
    "premise_still_valid": true,
    "summary": "Every world()-seeding case in test/flow-campaign-enrollment.test.ts (13 it + 4 it.each call sites, 17 in all) now passes WORLD_BUDGET_MS = 30_000 as its per-case timeout (trailing-argument convention, same size as ENROLL_BUDGET_MS in test/campaign-enrollment-doors.test.ts), with the measurement beside the constant; an empty-frontmatter changeset carries the claim's Clause-② and Metadata-protocol lines. Mechanism assumption holds: not a hang; the #2241 leads case runs 2.5 s alone and 4.9 s in a full local coverage run. The cases are not equal: an Enroll Members run enrols every eligible person the marketer can see and each world() adds 2 eligible leads + 2 eligible contacts, so per-run member counts grow 7 → 51 down the file (probe on a scratch copy, not committed) and the last leads case (:438 on this head) is the slowest; the PR says why.",
    "tests": "Isolated (base f660fd8): npx vitest run test/flow-campaign-enrollment.test.ts, 30 passed; enrolling cases 507-2528 ms, refused/structural 1-164 ms. Full local npx vitest run --coverage (CI's test:coverage), 4-core container: 239 files, 4592 passed, 1 skipped, 0 failed; enrolling cases 799-4947 ms, the two #2241 submit cases 4947 and 4906 ms (53 and 94 ms under the 5 s default). Head cb2c9c3 isolated: 30 passed. CI per-case: NOT MEASURED, reason: CI's default reporter prints per-file totals and names a case only on failure; the CI readings are the two 5000 ms timeouts at :424 on 0f17c6c and 173b488 (job 122642586187). No ablation: the diff changes no tested behaviour, only timeouts.",
    "gates": "pnpm verify (validate, typecheck, lint --strict, hygiene, hygiene:tokens, build, vitest run) exit 0 captured before any pipe: Test Files 239 passed (239), Tests 4592 passed | 1 skipped (4593), 824 s. The changeset's two claim lines landed mid-run, so pnpm hygiene (exit 0, source hygiene clean) and pnpm hygiene:tokens (exit 0, source token ratchet clean) were re-run on head cb2c9c3. dispatch-gates.mjs not used: hotcrm has none (derived by hand from package.json verify + .github/workflows). PR #2358 check-runs at report time: Vercel Preview Comments success, Label Pull Request success; Build and Test (22.x), Quality Checks, Check Changeset, Analyze Code (javascript), link-check, Playwright in_progress.",
    "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
    "mcp_calls": "7 — all reads: mcp__github__issue_read x5 (get 1, get_comments 4 incl. this report read-back), mcp__github__get_job_logs x1, mcp__github__pull_request_read x1 (get_check_runs); no MCP write",
    "api_writes": "2 — fleet-write relay pr_create (POST /repos/objectstack-ai/objectstack/dispatches → POST /repos/objectstack-ai/hotcrm/pulls draft + POST /repos//issues/2358/assignees, run 40643896996 success, body read-back 6332/6332 bytes identical, assignee huangyiirene); this os-dev-report comment via scripts/pm/post-stamped.mjs (POST /repos//issues/2357/comments)",
    "open_questions": [],
    "out_of_scope_findings": [
    "class: none (fixture design, not a defect) · reach: n/a · evidence: per-run member counts 7, 9, 11, 15, 17 (leads), 16-24 (contacts), 46 and 51 (#2241) because every world()'s eligible people stay eligible for every later run; retiring each world's eligible people after its case would make each run flat at about 7 members · carrier: none · noted in PR Acceptance notes, not filed",
    "deviation: the first push carried the harness's model-named Co-Authored-By trailer; amended to a model-free trailer and force-with-lease pushed within a minute on this platform-assigned branch (3eeaab9 → b494d58), before any PR or other reader · carrier: none"
    ]
    }


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · repo:hotcrm seat 1 · session session_01J8VVAnPkgK6CWrJa6t7Fk5 · 2026-10-28T07:09Z

    Reading Probe Result
    PR #2358 GET /pulls/2358 Merged 2026-10-28T06:31Z as 511b5f2 from head cb2c9c3c4c, the head the seat ACCEPTed (6462364465).
    main CI on 511b5f2 GET /commits/511b5f2/check-runs All 5 runs report success, Build and Test (22.x) included.

    State: the PR's closing line closed this card as completed, and this stroke removes its lane label. The 17 world()-seeding cases in test/flow-campaign-enrollment.test.ts now carry a measured 30 s budget. That gives about 6× headroom over the 4.9 s worst case that ran past the 5 s default on main twice. The member growth behind it is documented beside the constant.


    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

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions