Skip to content

fix(test-shards): judge pin 3c's slice count through a symmetric 5% band - #30138

Merged
objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/issue-29826-slice-pin-hysteresis
Nov 4, 2026
Merged

objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/issue-29826-slice-pin-hysteresis

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by 田騏 · project thread
Fixes #29826
Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:分片切片数校验(pin 3c)由"只认恰好一个切片数"改为两侧对称 5% 滞回带,一个常量 SLICE_COUNT_HYSTERESIS = 0.05。
  • 为什么改:CLI 测试时长的周间噪声(1339–1493 s)远大于 20 s 余量,每周自动刷新的计时数据 PR 会随机变红,需席位手工开车道 PR 才能落地。
  • 风险与回滚:只改自测接受哪个手写切片数;任何一次 CI 运行的切法、密度上限、整包腿上限都不读它。回滚即 revert 本 PR。
  • 先看:scripts/partition-test-shards.mjs 的 sliceCountProblems() 两个判定分支,其次是自测新增的 4 个带内/带外夹具。
  • 两分钟验证:node scripts/partition-test-shards.mjs --self-test,预期打印 self-test OK ... file-level slices: @objectstack/cli x2。
  • 需要你做的:无,席位落地。

What changes

Option D as ruled in comment 6634084947 on the card. One file: scripts/partition-test-shards.mjs.

  • New SLICE_COUNT_HYSTERESIS = 0.05, commented as the observed noise width of the CLI median.
  • sliceCountProblems() (pin 3c) judges both halves through the band. RAISE refuses only when weight / n > (1 + h) x limit. LOWER (or Retire) refuses only when weight / (n - 1) is at or under (1 - h) x limit. A count inside the band passes. Each refusal names the slice, the limit and the band edge, to two decimals. The count a RAISE names is still the smallest one that meets the bare limit, so a raised count lands with margin.
  • planShards() (NEEDED / SPREADS / WITHIN CAP), the density cap and pin 3d are byte-for-byte unchanged.
  • Self-test: 4 new pin 3c fixtures on the existing 50 s-filler fixture (limit 65 s, band 61.75 to 68.25 s). Two are in-band passes: RAISE side at 134 s / 2, LOWER side at 125 s / 3. Each is also run with no band, and there it must be refused, so the pass is proven to come from the band. Two are out-of-band refusals beside the edges: 138 s / 2 must say Raise it to 3 with one slice is 69.00s, and 122 s / 3 must say Lower it to 2 with one slice (61.00s). The balancing-pins battery floor goes from 25 to 29; it now registers 30 cases.
  • The FILE_SHARDED_PACKAGES "RE-DERIVED AT 2" paragraph gains one sentence saying why the band exists.

Tests

  • node scripts/partition-test-shards.mjs --self-test: exit 0 on head 1c0a83b762.
  • The four existing fixtures keep their verdicts at h = 0.05: PASS (120 / 2), Retire the entry (60 / 2), Lower it to 2 (120 / 3), Raise it to 5 (300 / 2).
  • Ablations, each through scripts/ablation-replace.mjs, restored to the HEAD blob with an empty git diff HEAD:
Ablation readings (self-test exit code and first failing case)
Mutation Exit First failure
SLICE_COUNT_HYSTERESIS = 0 1 a count of 2 inside the RAISE band was not passed by the band alone
LOWER branch judged against the bare limit 1 a count of 3 inside the LOWER band was not passed by the band alone
RAISE branch judged against the bare limit 1 a count of 2 inside the RAISE band was not passed by the band alone
SLICE_COUNT_HYSTERESIS = 0.07 1 a count of 2 past the RAISE band was accepted
SLICE_COUNT_HYSTERESIS = 0.1 1 a package that is not the floor kept its slicing with no refusal (an existing fixture)
battery floor 29 to 99 1 battery "the balancing pins (#10472)" registered 30 case(s), below its pinned floor of 99

Acceptance notes

  • Thresholds re-measured on the committed dataset (CLI 1432.04 s; floor @objectstack/metadata-protocol 566.50 s; limit 736.45 s). I called the exported sliceCountProblems() on the dataset binned the way the self-test bins it, varied only the CLI weight on a 0.01 s grid, and they agree with the ruling's figures. Map 2 is accepted for CLI 699.63 to 1546.54 s (ruling: up to 1546.5). Map 3 is accepted for CLI 1399.26 to 2319.81 s (ruling: over 1399.3 to 2319.8).
  • Card bullet 1: the dataset with the map at 2 passes, and so does CLI at 1480 s with the map at 2 (also 1493 s, the measured high run).
  • Card bullet 2: a drift past the band still refuses with the numbers. At CLI 1546.6 s with map 2: one slice is 773.30s -- past 1.3x ... (567s, so 736.45s) by more than its 5% band (773.27s) ... Raise it to 3. At CLI 1399.2 s with map 3: at 2 one slice (699.60s) ... with more than its 5% band to spare (699.63s). Lower it to 2.
  • Floor-side reading by the same formula: with the CLI at 1432.04 s, map 2 holds while the floor stays at or above 524.56 s.
  • The nominal RAISE bound in the self-test moves from 1.3x to 1.365x. The maintainer ruled on that tradeoff (option D). No run's split reads it.

Verification

All 31 commands that node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derives for this diff exited 0. The exit codes were captured before any pipe, and --ran reconciliation reports 31 derived, 31 run, 0 NOT-MEASURED, 0 UNRUN (a derived zero: all 31 recorded an exit code). pnpm check:pm-dispatch-gates (fast tier, 1945 cases) also exited 0. The CI-only Plan Test Core shards step and the type-check lanes are not measured locally; CI runs them. skip-changeset: the diff touches only root scripts/, which no package publishes. origin/main was merged once before opening.

Session: https://claude.ai/code/session_017ihL2ebbZkr2QAEG1x7UC8

🤖 Generated with Claude Code

Pin 3c accepted exactly one slice count, so a CLI median moving 20s inside
its own run-to-run spread flipped the derived count and redded the weekly
generated refresh PR until a hand-written lane PR changed the map.

SLICE_COUNT_HYSTERESIS = 0.05 now bands both halves: RAISE refuses only a
slice past 1.05 x the serial-floor limit, LOWER only an n - 1 slice at or
under 0.95 x it, and a count inside the band passes. The remedy a RAISE
names is still the smallest count meeting the bare limit. planShards(),
the density cap and pin 3d are unchanged. The self-test gains two in-band
passes (each refused with no band) and two out-of-band refusals beside the
band's edges; the four existing fixtures keep their verdicts.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017ihL2ebbZkr2QAEG1x7UC8
At the band's edge a whole-second slice and band read the same number
(773s past 773s); two decimals show which side of the edge it fell.

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

Copy link
Copy Markdown
Contributor Author

domain:devx#2 · marchtian · session_017ihL2ebbZkr2QAEG1x7UC8

席位核对 — ACCEPT · domain:devx#2 · Head-sha 1c0a83b762f16c0a09b0a537cc68ecba009ceb3c · 2026-11-04T15:45Z

  • Shape: one file, scripts/partition-test-shards.mjs, +89/−13 (read from the diff, not the report). Root scripts/, not a governed path, no published package, under 3000 lines: Tier S landing by the seat.
  • Against the ruling (6634084947, option D): one constant SLICE_COUNT_HYSTERESIS = 0.05 with a comment naming it the cli median's noise width; RAISE refuses only at weight / n > (1 + h) × limit, LOWER/Retire only at weight / (n − 1) ≤ (1 − h) × limit; refusals carry the slice, limit and band edge. planShards(), the density cap and pin 3d are untouched in the diff. Four new fixtures: two in-band passes, each also proven refused with the band off; two out-of-band refusals within a second of the edges. The existing four keep their verdicts. The "RE-DERIVED AT 2" docblock gains the band sentence.
  • Measured (report 6634782651): map 2 holds for cli 699.63–1546.54 s and map 3 for 1399.26–2319.81 s, matching the ruling's figures, so h was not tuned. Card bullets: cli 1480 s and 1493 s at map 2 pass; past the band, Raise / Lower still name the numbers. Six ablations each turn the self-test red.
  • Gates: every check-run on the head is success (26) or skipped (20); check-expected-skips OK. Local dispatch-gates --commands 31/31 exit 0, --ran reconciled; partition-test-shards.mjs --self-test exit 0.
  • Accepted deviations: refusal text now prints two decimals (no consumer parses it); the balancing-pins battery floor 25 → 29 for the four new cases; the origin/main merge commit carries git's default message.
  • Out of scope: a future RAISE past 1546 s likely goes straight to x4 because planShards cannot spread x3; that is planShards behaviour, not this card, and is not filed until it happens. Skills-docs: n/a, Metadata-protocol: none.
  • Landing: skip-changeset (root scripts/). Ready, then auto-merge through the merge queue.

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review November 4, 2026 15:46
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Nov 4, 2026
Merged via the queue into main with commit 2381085 Nov 4, 2026
47 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-29826-slice-pin-hysteresis branch November 4, 2026 16:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ci(test-shards): the slice-count pin has no hysteresis, so a 20 s drift flips the CLI map and turns the weekly refresh red again

1 participant