Skip to content

test(plugin-pinyin-search): seed the boot-reconcile history in batches and give the kernel suite a 30 s budget - #25775

Merged
objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/project-thread-mlk7r2
Oct 25, 2026
Merged

objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/project-thread-mlk7r2

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Requested by Leehom · project thread

Fixes #25749
Fixes #25750

The anchor #25750 closes with this fix (triage 6394128781); the seat claim on it, 6396273722, names this branch.

Clause-②: no
Metadata-protocol: none

What changed

One file, test-only: packages/plugins/plugin-pinyin-search/src/boot-reconcile.integration.test.ts. Production source and vitest.config.ts are untouched.

  1. Route (a), the seed. FixturePlugin.directInsert wrote the 2,500-row history with one awaited driver.create per row. It now calls driver.bulkCreate in slices of 500 rows, five statements in all.
    • A single 2,500-row bulkCreate does not work on SQLite. Measured: all 7 seeded cases fail in boot with SQLITE_ERROR: too many terms in compound SELECT. driver-sql sends a batch as one insert … select … union all select … statement, and SQLite's default compound-SELECT ceiling is 500 terms. Hence the slices (INSERT_BATCH = 500).
    • bulkCreate keeps the given created_at / updated_at. stampInsertTimestamps only fills a null or missing column, the same function create() calls, so the HISTORIC stamps the watermark cases rely on are unchanged. Every assertion is unchanged too, and they still pass.
  2. Route (b), the budget, added on measured evidence. With the seed batched, 2 of 8 cases still went past 5 s under load. A timing probe (one-off, not committed) showed the seed costs only 0.2 to 0.6 s under 20 busy loops. The rest of the time is the real-kernel boots and the 2,500-row reconcile walks the cases exist to measure: 6.8 s for the first-boot/second-boot case and 10.1 s for the forced rebuild, seed excluded. So the kernel-booting describe gets { timeout: 30_000 } (the packages/runtime/*integration.test.ts precedent), with a comment that names the boots and walks it pays for. The fake-engine describe stays on the default.

Measurements

4-core container, pnpm --filter @objectstack/plugin-pinyin-search exec vitest run --maxWorkers=2 --reporter=verbose src/boot-reconcile.integration.test.ts. "Load" means 20 busy loops (while :; do :; done), the load used in reproduction 6394530515. Each run held scripts/pm/os-verify-lock.sh. Times are per test in ms; ✗ means Test timed out in 5000ms.

case main idle (2 runs) main load (2 runs) head idle head load (2 runs)
first boot walks every row; unchanged second boot reads none 1474 / 1578 8125 ✗ / 8450 ✗ 1335 6744 / 7884
second boot fills a row a hook-bypassing writer added 985 / 974 6752 ✗ / 5720 ✗ 585 3834 / 4142
control: hook write stamps __search, reconcile off the boot path 789 / 865 6270 ✗ / 6720 ✗ 446 3868 / 3502
control: forced rebuild walks every row 1473 / 1502 10363 ✗ / 11576 ✗ 1139 8373 / 8543
readiness does not wait for the reconcile 897 / 880 7207 ✗ / 4676 454 3078 / 3638
shutdown stops the reconcile between pages 901 / 864 5745 ✗ / 5420 ✗ 577 3164 / 3661
without the ledger every boot walks every row 874 / 793 5201 ✗ / 6187 ✗ 454 3008 / 2816
a failing reconcile is logged (fake engine) 4 / 5 53 / 24 5 30 / 34
result 8/8, 8/8 1/8, 2/8 8/8 8/8, 8/8

The intermediate commit, with the seed batched and no budget (11d10c22), ran 8/8 idle twice (slowest 1094 ms). Under load it ran 6/8: first-boot 6899 ✗ and forced rebuild 9482 ✗. That is the measurement behind route (b).

The secondary error Cannot open database because the directory does not exist shows up 10 and 6 times in the two main load logs and 0 times in the three head logs. It was fallout from afterEach removing the temp directory under a timed-out body, and it goes away with the fix, as the order expected. It was not patched separately.

Verification at head d1f610e4d1

  • pnpm --filter @objectstack/plugin-pinyin-search typecheck: exit 0 (check:test-typecheck: OK, 0 errors).
  • pnpm --filter @objectstack/plugin-pinyin-search test: Test Files 4 passed (4), Tests 39 passed (39). Lock verdict command-exit 0.
  • eslint packages/plugins/plugin-pinyin-search --no-inline-config: exit 0.
  • Derived gate families (node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack, 57 commands): 56 exit 0. pnpm check:dual-build-cjs-loads exited 3 (PREREQUISITE NOT MET: no dist/ for about 53 packages without a full workspace build), so it is NOT MEASURED locally and CI's run is the measurement. --ran reconciliation, with exit codes recorded: 57 derived, 56 run, 1 NOT-MEASURED, 0 UNRUN. node scripts/check-plugin-teardown-shape.mjs --self-test exited 3 on the first pass from a shallow clone, then 0 after git fetch --unshallow. The final pass at this head recorded 0.
  • No ablation. The diff changes a fixture's write path and a timeout. It changes no behaviour the tests pin, and every assertion is byte-identical.

Acceptance notes

  • SqlDriver.bulkCreate on SQLite refuses a batch of more than 500 rows (too many terms in compound SELECT). The in-tree batch callers stay under that limit: seed-loader.ts BULK_BATCH_SIZE = 200, core/src/utils/bulk-write.ts DEFAULT_BATCH_SIZE = 200, import-runner.ts MAX_CREATE_BATCH_SIZE = 200. I measured no public door that reaches it, so this is an observation, not a filed card. Carrier: none.
  • The second commit's message says the forced-rebuild walk took 9.9 s. The probe measured 10,288 ms with a 222 ms seed, which is 10.1 s. The third commit corrects the code comment. The pushed message is left as it is, with no history rewrite.
  • skip-changeset: test-only. A *.test.ts file is outside the package's files[] (dist only), so nothing published changes.

🤖 Generated with Claude Code

https://claude.ai/code/session_01T5digj2EfFsbXihqJEo1ix


Generated by Claude Code

…d bulkCreate calls

The fixture wrote its 2,500-row history with one awaited driver.create per
row. Batched bulkCreate (500 rows, SQLite's compound-SELECT ceiling) cuts
the seed to five statements.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T5digj2EfFsbXihqJEo1ix
With the seed batched, the remaining cost under load is the real-kernel
boots and the 2,500-row reconcile walks the cases exist to measure. On a
4-core box with 20 busy loops they alone took 6.8 s and 9.9 s, past
vitest's 5 s default. The budget sits on the one describe that boots the
kernel; the package config stays on vitest's defaults.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T5digj2EfFsbXihqJEo1ix
…get comment

The forced-rebuild case measured 10,288 ms with a 222 ms seed, so the
boots and walks alone took 10.1 s, not 9.9 s.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T5digj2EfFsbXihqJEo1ix
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 25, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

Nothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 0 changed package(s)), so this run has no opinion about the docs.

What this run could not see

Coarse fallback — 0 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json f0cf3383306a2bd585f5ae88577aae1d68308bae → packageMentionDocs.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对 · ACCEPT · domain:server seat 1 · os-project-manager · session_01R1q2xdtYgU6FKrZ7LgjPCC · 2026-10-25T10:06Z

Head d1f610e4d1, report 6396258019, claims 6395622857 (#25749) and 6396273722 (#25750).

item reading
Shape draft, base main, Fixes #25749 + Fixes #25750, skip-changeset label (test-only). The closing-target claim guard re-ran on the body edit and is success (run 40183296654); the first run failed only because the anchor carried no claim yet.
Files (1, +20/−3) packages/plugins/plugin-pinyin-search/src/boot-reconcile.integration.test.ts: exactly the claim's surface. No production source, no vitest.config.ts, no packages/spec/**, so no contract review is owed. Not governed (check-governed-merges --pr 25775), 23 changed lines.
Route (a) then (b), both inside triage 6394123768: directInsert seeds through bulkCreate in 500-row slices (SQLite refuses more than 500 compound-SELECT terms, measured by the dev), and the kernel describe carries { timeout: 30_000 } with a comment naming the boots and walks it pays for, because the dev measured those alone at 6.8 s and 10.1 s under 20 busy loops. ⛔ No skip, quarantine or retry. The 30 s figure matches packages/runtime/*integration.test.ts.
Evidence under 20 busy loops: head 8/8 twice, main 1/8 and 2/8. Every case's assertions are unchanged.
Gates dev 56/57 exit 0; check:dual-build-cjs-loads exit 3 (the shallow-clone prerequisite, CI's Build Core owns it). CI at this act: in progress.
Landing ready + auto-merge through the relay once every check on this head is green or an expected skip. Then #25740 (#25467 cut 10) is re-armed.

Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 25, 2026 11:24
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 25, 2026 11:24
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 25, 2026
Merged via the queue into main with commit c1bb4b5 Oct 25, 2026
59 of 60 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-mlk7r2 branch October 25, 2026 11:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate tests

Projects

None yet

2 participants