Repository navigation
test(metadata-protocol): lock-one-resolution takes each distinct read request's reads once, 20 s to 8.4 s (#23182 row 1) - #23755
Merged
objectstack-fleet[bot] merged 3 commits intoOct 16, 2026
Conversation
…request's reads once (#23182 row 1) Claude-Session: https://claude.ai/code/session_01ADzJtzYTLUfgrRZHxkagkX Co-authored-by: Claude <noreply@anthropic.com>
… and skips matchers for equal pairs (#23182 row 1) Claude-Session: https://claude.ai/code/session_01ADzJtzYTLUfgrRZHxkagkX Co-authored-by: Claude <noreply@anthropic.com>
… request's reads once and skips matchers for equal pairs (#23182 row 1) The file's 16 320 generated rows run 28 848 times (reads, then a door) once the store and registration orders are counted. The two reads take no organization and no verb, so the four rows that differ only in those share one protocol instance and one pair of reads (7 212 distinct requests); each row still asserts for itself. The oracle's answers are asked once per row, and the matcher is built only when a pair differs. Same 16 360 tests, same order, same titles. Claude-Session: https://claude.ai/code/session_01ADzJtzYTLUfgrRZHxkagkX Co-authored-by: Claude <noreply@anthropic.com>
Contributor
📓 Docs Drift CheckNothing 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): |
This was referenced Oct 16, 2026
objectstack-fleet
Bot
deleted the
claude/issue-23182-lock-one-resolution-budget
branch
October 16, 2026 01:07
This was referenced Oct 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #23182 (row 1)
Clause-②: no
This PR covers row 1 of #23182 only:
@objectstack/metadata-protocol,src/protocol.lock-one-resolution.test.ts, 113.2 s in run38228297391. It changes one test file and no production file. It takes the file from about 20 s to about 8.4 s alone on this box, and it does not by itself get the file under the 10 s line under CI-shaped contention (27.5 s in the package-suite reading below). The fork that is left is a maintainer's call; it is under "What is left" and in the dev report. #23182 stays open: this PR does not close row 1, and row 5 is its own card of work.Where the time went
Measured at BASE
534ca13eb5(vitest module line, default reporter, a shared 4-core box underos-verify-lock):getMetaItem6.9 s andgetMetaItemLayered4.9 s (28 875 calls each), the doors 2.25 s,vi.spyOn0.77 s, building the instances 0.48 s, and about 5.5 s for matchers, the oracle and the runner.envelopeignores its organization argument, and neither read has a verb). The table's rows that differ only inrequestScopeandoperationtherefore asked the same two reads of the same data four times each: 28 848 read runs against 7 212 distinct requests, exactly 4 to 1.What changed (test only)
readScenario: one protocol instance per distinct read request, its two reads taken once. The key is the request's real inputs: the environment, the stored rows and the artifacts in the order the store and the registry return them, the type spelling and the package. It is not a description of a row, so two rows share an instance only when every input the reads take is byte-equal. The instance a row's door then runs on is the one its reads ran on, so the header's "ONE protocol instance" still holds (a read still precedes every door on its instance). What is new is that a door can also follow another door on that instance; every row passes under both shapes, and the red sets below are equal on both.expectedLockwas called five times per run).agree:expect(actual, message).toEqual(expected)for the table's hot path.isDeepStrictEqualimpliestoEqual's equality, so when a pair is strictly equal the matcher would pass and is not built; when a pair differs the real matcher runs and fails with the message and diff it always gave. The table made well over a hundred thousand matchers (about 2 s of the wall).expectthat the rows made is still made on the same pair, the 16 360 tests keep their titles and their order, no case is deleted, skipped or moved, and no timeout is touched.doorstill ends at the realsaveMetaItem/deleteMetaItem: a refusal anywhere in the write path is still the verdict (I did not stop the write at the gate, because "end to end" is what the door's doc says it pins).Wall time
Vitest module line in ms, a shared 4-core box under
os-verify-lock,--maxWorkers=2, file alone; BASE and AFTER runs interleaved:534ca13eb5f214779c156717655b7f, same code: 8258 / 8359 / 8779)--maxWorkers=8(2x oversubscribed)1dc5a6150e, 10.8 s) read: the two reads 3.7 s (7 239 calls of each), the doors 2.0 s,vi.spyOn0.55 s, the rest of the row bodies 3.2 s and the runner 1.4 s. The hoist andagreethen took about 2 s out of the last two. So the protocol's own calls, the reads and the doors, are about 5.7 s of the 8.4 s, and they cannot be shared further without changing what a row asks.Ablation: the pins still go red, on the same rows
Each leg mutated production source through
scripts/ablation-replace.mjs(anchor 1 to 0, the replacement counted, the blob changed), ran a temporary copy of the BASE file and this branch's file in one vitest run, and was restored to the HEAD blob withgit diff HEADempty. The subject is imported by relative path fromsrc, so nodistis in play. The temporary BASE copy is deleted.item-lock.ts)item-lock.ts,resolveItemLockLazily)item-lock.ts,withItemLockFamily)protocol.ts, temporary, restored)The first failure of A2 reads "the door: expected 'admitted' to deeply equal ..." on both files, so the failing path of
agreereports the message and diff the plain matcher did.Verification at
f214779c15pnpm --filter @objectstack/metadata-protocol typecheckexits 0;tsc --listFilesnames the test file once.eslint --no-inline-config --format jsonreports 1 file, 0 errors and 0 warnings.--print-configreturns a config for the file, and its parserOptions areecmaVersionandsourceTypeonly, so type-aware linting is off and this diff cannot move any other file's result.dispatch-gatesover the one path derives 51 commands. All 114 distinct commands (the 51, plus the 53 artifact-roster and 11 wide-population families it names, one shared) ran at this head after a fullturbo run build(74 tasks): 110 exit 0 and 4 exit non-zero. The 4 are PR-context guards that judged nothing and say so:check-closing-target-claim(2) andcheck-single-claim-paths(2) need a PR number and a token,check-governed-queue-guard(1) needs the event payload,check-partof-closing-keyword(2) needs a PR body (re-run below with this body). They are NOT MEASURED, not red.check:nul-bytesexits 0 (inside the 114).No changeset
This diff changes only a test file under
packages/metadata-protocol/src, whichfiles(dist,README.md,CHANGELOG.md) does not ship.skip-changesetis the label, as on the earlier rows.What is left (the fork)
The single file's floor on this box is about 8.4 s, of which 5.7 s is the protocol's own calls over the 7 212 distinct reads and 28 848 doors. Under CI's contention that is about 27 s. Two routes get the file off the next refresh's list, and neither is mine to take:
scripts/engine-double-contract.pinned.json. It costs one import ofprotocol.tsper extra file.test-budgetclasses inmeasure-test-shard-timings.mjsnames a generated-product enumeration, so it needs a ruling for the class as well as for the file. Only the maintainer grants it.Acceptance notes
Generated by Claude Code