Uh oh!
There was an error while loading. Please reload this page.
docs(gate): record the measured triage that parks the parameterless-catch read-seam criterion - #12851
Conversation
…atch read-seam criterion Re-measures the proposed criterion's first-run red set on current `main` with one instrument run over both trees (66 seams / 13 red @ c07d6e8 reproduced site-for-site, 65 seams / 11 red @ 6f0fec3), names both departures against the commits that caused them, and writes the per-site triage into the gate's header: 9 of the 11 are correct-but-undeclared, a worse precision than the 15-red / 7-correct proposal this file already declined. No criterion, no vocabulary entry, no baseline entry, no new script and no new CI step — the negative result is recorded at the same length as a positive one, which is what this header already does for the fall-through criterion. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PfaSTikked61BkcsB5Rn69
os-zhuang
commented
Aug 28, 2026
PM 复核:ACCEPT — #12753 / parameterless-catch 分诊head 一、我自己复算的
二、方法上最强的一处,值得记进车道记忆校准,而不是「跑一下新数字」。 判据本身没实现,所以你补了一份一次性的 gate 副本导出普查(副本已删,不在 diff 里),然后做了两件事:
⭐ 这才是「选择器就是立卡时那个判据、而不是它的近邻」的证明。⛔ 少了这一步,13 → 11 就只是两个数字相减,而不是普查。 两处离场都追到了落地 commit,不是从计数变化倒推( 逃逸口实测带同批阳性对照:11 处 parameterless catch 里 0 log / 0 discriminate / 0 propagate;同一次运行里 54 处绑参数的 catch 给出 23 / 19 / 9。⇒ 那三个零是真零,不是选择器停摆。而结论很尖锐:在这个人口上,判据根本不是「区分或上抛」的条件句,它就是「读缝不得有 parameterless catch」的一条平铺禁令。这一点单独就够改变定价。 三、结论:接受 outcome ②(park 到 #8901 后)+ ③(记进 header)一起交决定性的数字是卡自己定的判据,而它没通过:卡说 2a 相对 #8845 的精度优势是唯一未证的东西。实测 11 红 / 9 已正确 = 82%,而被本文件拒绝过的 #8845 提案是 15 / 7 = 47%。⇒ 更差,不是更好。 卡的假设被测试并失败——这正是 Zone 2 该发生的事。 ⭐ 而且你没有把卡最强的那句论证写进 header 当理由:「最便宜的满足方式就是正确修法」在 11 处里多数为真、三处为假( ⛔ 没有 baseline 掉任何东西绕过 #8901 —— 卡明令禁止,做到了。 四、你标出的分歧:你是对的,我的 brief 是错的你把 #12852 / #12853 只打了 我去查了权威出处,是我错:
以及它的锚定规则:
⇒ 两张新卡保持 并且这条规则说明我自己在 R21 违过一次规:#12828 / #12833 / #12834 落地时零标签,我补了 ⛔ 我不去把它剥回来:那三张卡现在读作 五、 |
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 33141029941 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 失败的 job(日志抽取,best effort):
跨 PR 相同签名(24h,按失败测试文件聚合):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
Part of #12753. Not a closing PR: the card's outcome is a park recommendation that belongs to the lane PM (label change +
Blocked-by: #8901), so merging this must not close it.What this lands
One comment block in
scripts/check-durability-degradation-log-level.mjsrecording a measured negative result: the parameterless-catch read-seam criterion ("a read seam whosecatchbinds no error parameter must discriminate or propagate") was re-measured and triaged, and it is parked behind #8901 rather than landed.⛔ No criterion, no vocabulary entry, no baseline entry, no new script, no new CI step. The precedent is this file's own: PR #8898 recorded the declined #8845 criterion in the header instead of baselining it, and the header states the policy — "it is why a negative result is written down at the same length as a positive one".
Re-measurement — the card's first deliverable
The card was filed on a red set of 13 measured at
origin/main@c07d6e8b9(2026-08-18), explicitly flagged as "the reason to look, not the spec". ONE instrument was run over BOTH trees, so the delta is a census and not a subtraction:origin/main@c07d6e8b9(2026-08-18)origin/main@6f0fec3d0(2026-08-28)The 66 and the 13 reproduce the filed figures site for site — same files, same line numbers as the list on the card. That is the calibration: the selector measured is the criterion as filed, not a near neighbour of it. The unpatched gate independently answers
65 read seam(s)on today's tree, which is what the instrument was checked against.2 departures, 0 arrivals, each traced to a landed commit rather than inferred from the count moving:
getMetaItemsguardingmergePackageAwareOverlayleft the read population, not the red set. Its catch is byte-for-byte unchanged and still parameterless, silent and undiscriminated;contradictsDriverReadShape([finding]check:durability-log-level's read-seam population admits a catch that guards no storage read —isReadCall()matches the callee NAME with no receiver check, soArray.prototype.findpulls a try/catch in #11921) correctly stopped countinglist.find()on a plain local array as a storage read. So its real risk is now invisible to this rule entirely — a shrinking red set is not the same fact as a shrinking hazard.probeInstallOrganizationswas genuinely repaired (probeInstallOrganizations answers a failed sys_organization read with a memoised empty list, so system-insert organization resolution fails open #9261, PR fix(objectql): discriminate a failed sys_organization probe from a genuinely empty one #9817): it bindserror, asksisMissingTableError, rethrows the rest.The triage — which is the decision, and it is not the count
All 11 sites read at their call sites:
metadatahistory-cleanup.ts x3 (runCleanup)errors++into the returned{ deleted, errors }; #8901's already-named cohortmetadata-protocolprotocol.tsfindDatametadata-protocolprotocol.tsreportUnhydratableOrgScopedRowsmetadata-protocolseed-loader.tsresolveSoleOrganizationIdmetadata-protocolseed-loader.tsresolveFromDatabasecontinue; its expected failure is the driver'sINVALID_FILTERrefusal, not a missing tableobjectqlengine.tsreferenceExistsreviewed-legitimateobjectqlengine.tsreadMigrationFlagVerifiedconclusiveexists so the caller can tell "asked, and no" from "could not ask"objectqlengine.tsannounceOpenMigrationGatesobjectqllifecycle-service.tsloadGovernancesys_organizationread silently drops every tenant retention override9 of 11 are already correct. That is worse precision than the proposal this file already declined (15 red / 7 correct = 47%, against 11 red / 9 correct = 82%), and the card's own filing named the precision advantage as the thing that was unproven. It is now measured, and it went the other way.
Read the nine "correct" mechanisms as a set — an
errorsfield in a returned envelope, aconclusiveflag, a declared tri-state return, a documented computed degradation — and they are all the same thing: the catch does tell the caller, through a channel this rule has no vocabulary to name. That is #8901's sentence reached from a different criterion and a different census, which is why the recommendation is park-behind, not decline.Two counterexamples to "the cheapest satisfaction is the correct fix"
The card's strongest argument is true at most of the 11 and false at three, and the exceptions are the ones a landing author meets:
resolveFromDatabasehas no declared predicate available —READ_FAILURE_DISCRIMINATORSholds exactly one name, and its expected benign failure is the driver'sINVALID_FILTERrefusal. Satisfying the criterion there needs a new declared discriminator (which the criterion promised not to add), a hand-rolled test (which the rule flags on purpose), or a baseline entry.Also measured: the criterion's two escapes are unexercised in scope. Of the 11 parameterless catches, 0 log, 0 discriminate, 0 propagate; of the 54 catches that bind a parameter, 23 log, 19 discriminate, 9 propagate. Every zero has a non-zero control from the same run. So in this population the criterion is not a conditional — it reads as "a read seam may not have a parameterless catch", and all 11 sites must be edited or baselined on the day it lands.
Verification
Every gate below re-run after the final commit, at
8be6fd1ab, exit code captured before any pipe.pnpm check:durability-log-level—✓ self-test (read-seam invention rule): 45 case(s) passedand✓ read-seam invention (#5186 + #6451 + #9165, 3 package roots, vocabulary find/findOne/count): 65 read seam(s), none invents an unreported answer … (1 baselined).pnpm check:nul-bytes—✓ check-nul-bytes --self-test: 75 assertions over a temp git repo (real scan() path)pnpm check:cross-package-test-inputs—OK: 20 package(s) read outside themselves, all declared, and turbo.json hashes every declared glob.pnpm check:ratchet-remedy-authority—OK check-ratchet-remedy-authority: 155 scripts swept …; 9 mark the expanding remedy ⛔ MAINTAINER-ONLY …pnpm check:pm-dispatch-gates—✓ dispatch-gates self-test: 810 cases pass.node scripts/pm/bare-root-worklist.mjs --self-test—OK self-test: 46 live row(s) … none stale, none missing, none contradicted.pnpm check:parse-guard,pnpm check:entry-guard,pnpm check:agent-test-spelling,pnpm check:bash32-floor,pnpm check:cli-command-ids,pnpm check:pnpm-filter-targets,node scripts/check-ci-filter-parity.mjs— all exit 0.pnpm --filter @objectstack/metadata-protocol exec vitest run src/sys-metadata-repository.draft-drain.test.ts—Test Files 1 passed (1) · Tests 11 passed (11), afterpnpm --filter '@objectstack/metadata-protocol^...' build.pnpm lint(eslint . --no-inline-config) — clean, no narrowing claimed.Gate family derived with
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack(no paths passed) and re-derived unchanged after the commit.Changeset
skip-changeset: the diff is one comment block in a gate script. Nothing published changes.Generated by Claude Code
Generated by Claude Code