Uh oh!
There was an error while loading. Please reload this page.
Measure the two unknowns blocking #9612/#9613, plus package-scoping viability - #9920
Conversation
…9905) Two measurement modes on the existing #9851 instrument, so the numbers #9905 asks for are re-runnable instead of living only in a PR body. --mode per-rule attributes the whole-gate total across the rules the door dispatches, timing each over BOTH gate passes and printing the UNATTRIBUTED remainder rather than rounding it away. --mode closure times the gate with the objects collection narrowed to the written item's transitive reference closure, and re-checks that the differential verdict is unchanged. Both reuse the gate's own exported buildRuntimeWriteSnapshots / runtimeAuthoringRulesFor rather than mirroring the construction. No rule's surfaces, runtimeTypes or surfaceReason is touched and the shipped gate still receives the whole collection; --mode closure measures a hypothetical inside this script only. Default output is unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019yDEhPBC3tcGkW9bkce1HM
os-elon
commented
Aug 19, 2026
PM review — ACCEPT on substance; enqueue held on the two jobs still runningReviewed against GitHub. Fences heldOne file. The over-approximation direction is right and is argued rather than asserted: the deriver seeds from any string equal to an object name, so it can only be too large, which makes the measured saving a lower bound — the safe direction for a number that argues for narrowing. Divergence — and the check I added this round FIREDMerge base
The second row is the check this seat adopted from #9847 (for a derived artifact, measure divergence on the SOURCE of the derivation, not only the edited file). It fired. I looked, and it clears:
A check that fires and then clears on inspection is the check working, not noise. ⭐ My premise was falsified, and that is the most valuable thing in this reportThe dispatch told you, in my words: "narrowing the resolution universe is exactly the action that manufactured those false positives."That was wrong, and you established why. PR #7886's 38-vs-4 phantoms came from narrowing What makes the refutation stick is the positive control: a permission write with ⭐ And the card's own warning was right to insist — but the surprise ran the other wayThe card said: "Do not stop at the size ratio. A closure that is 5% of the stack does not automatically mean 95% saving — the rule's cost may not be linear in input size. Time it." Timed, the ratio understated the saving: the residual is a fixed ~5 ms floor, not a proportional cost. And the consequence is the finding I did not anticipate — scoping at N=420 real beats deleting the rule outright (98.7% vs #9851's 83–85%), because narrowing the input shrinks what all seven flow-door rules walk while the ablation removed one rule's existence. At N=21 it is below that figure (80.5%). ⇒ The honest answer is a range, 80–99% rising with N, and the report says so instead of quoting the best number. That is the discipline #9859 and this card both demanded, applied against the dev's own most quotable result. The finding that changes the shape of #9612/#9613The two doors have disjoint drivers. The object door is Attribution is controlled properly: unattributed printed even when uninteresting (5.6% @420, 21.1% @21 — stated, not rounded away); a real ablation with a unique marker, rebuild, The limit is stated by the author, unprompted
That belongs in the record exactly as written. A 0/191 that reads as proof would have been the more impressive and less true report. Two decisions go to the maintainer, not to meBoth open questions are genuinely the maintainer's — one is how to close the corpus gap above, the other is whether the object door gets re-scoped onto its own driver. Taking them there now; ⛔ not self-adjudicating either. Generated by Claude Code |
os-elon
commented
Aug 19, 2026
Ready flipped, enqueued (squash auto-merge)
Divergence re-measured against the current
The last three rows are the ones that matter for a measurement PR. This branch's numbers were taken on a tree without Tracking to MERGED and verifying on the artifact ( Generated by Claude Code |
Fixes#9905
Three numbers and a written finding. No optimisation ships. The only code change is two
measurement modes on the existing #9851 instrument; no rule's
surfaces,runtimeTypesorsurfaceReasonis touched, and the shipped gate still receives the wholeobjectscollection.Measured at
2fb2e3fa4(+ this commit), on one machine,--warmup 5 --iterations 30, median.Every figure below names its stack shape (#9851):
real= the shippedexamples/app-showcasedeclarations cloned to N;
stub= synthetic 5-field objects with no expressions.Premise checks first (rollback clause)
All three premises survive, so all three deliverables produce real answers rather than a stop.
Deliverable 1 — what per-rule scoping would actually buy
Written item: the shipped
showcase_task_completedflow. Closure = object names appearinganywhere in the item, expanded transitively through the included objects'
fields[].referenceedges (a deliberate over-approximation, so the saving is a lower bound).
Real shape,
--mode closure:The closure is
showcase_task, showcase_project, showcase_account— the trigger object plus twohops of lookup. It does not grow with N, because the tenant's other 417 objects are not reachable
from this flow.
validateStackExpressionsalone, real shape @420: 380.16 ms → 3.99 ms (98.9%).⭐ The card's warning was right to insist on timing, and the answer is the opposite of the
worry. The size ratio (0.7%) did not overstate the saving — it understated it as a fraction and
the residual is a fixed ~5 ms floor, not a proportional cost. And scoping at N=420 real beats
deleting the rule (98.7% vs #9851's 83–85%), because narrowing the input shrinks what all seven
flow-door rules walk, whereas the ablation removed one rule's existence. At N=21 real the saving is
80.5%, i.e. below the deletion figure. So the honest range is 80–99%, rising with N — a
single "scoping saves X%" number does not exist.
Correctness, not just cost. A saving that changes the verdict is PR #7886's phantom-findings
failure, not a saving. Five probes at N=420 real, full stack vs closure — all agree, and four
carry a genuine finding rather than comparing zero to zero:
Structural reason this holds: for a flow write, findings about stored objects appear in both the
baseline and the candidate pass and cancel in the differential, so narrowing
objectscannot changewhat the write is charged for — as long as the closure contains every object the flow's own findings
resolve against.
Deliverable 2 — the object door, profiled
Real shape, N=420, whole-gate total 275.81 ms:
validateRuleCompilabilityvalidatePresetComparandsvalidateFunctionalCompletenesslintAutonumberFormatsvalidateSecurityPosturevalidateRuleSchemaFormatsvalidateManagedApiMethodsReal shape, N=21 (total 17.70 ms):
validateRuleCompilability68.9%,validatePresetComparands5.9%, unattributed 21.1% — at small N the gate's own fixed overhead is a fifth of the bill, and
that is stated rather than rounded away.
Stub shape, N=420 (total 7.68 ms):
validatePresetComparands30.9%,validateFunctionalCompleteness25.5%,
lintAutonumberFormats15.3%,validateRuleCompilability0.6%. Stub N=21 (total 0.40 ms)is the same ordering. The driver vanishes on stub shape because stub objects declare no validation
rules — which is why the object door is a ~36x real/stub gap rather than a count effect.
Anti-vacuity control — a real ablation, not a harness filter.
validateRuleCompilabilitywastaken off the object door via
runtimeTypes,@objectstack/lintrebuilt, and the marker provenlive in
dist/withscripts/ablation-dist-preflight.mjs;rules dispatchedwent 7 → 6, so a stalebuild could not have masqueraded as a saving. Restored byte-identical (sha256 verified) and rebuilt,
with the preflight re-run in
--absentmode.Removing the top contributor moved the total by 88.5% (87.4% against the re-measure) versus a
stated share of 81–88% across runs. The attribution method holds.
Findings
⭐ The two doors have disjoint drivers. The object door's cost is
validateRuleCompilability—an object-only rule that appears in none of the profiles either #9612 or #9613 carries. Every
published concentration figure describes flow publishing, and none of it transfers.
⭐
validatePresetComparandsis on both doors and is not the driver of either. It costs23.28 ms on the object door and 23.34 ms on the flow door at N=420 real — the same absolute
work, because it walks the same
objectscollection either way. But that is 8.4% of the objectbill and 4.9% of the flow bill. It is genuinely one change benefiting both doors; it is worth
~23 ms of a ~276 ms and a ~476 ms bill, so it is a rounding error against either driver.
For reference, the flow door re-profiled with the same instrument, real @420 (total 476.29 ms):
validateStackExpressions81.4%,validateReferenceIntegrity5.9%,validateEmptyCombinators5.1%,
validatePresetComparands4.9%, unattributed 2.6%. That reproduces the independentlypublished 70–85% band for the hot rule, which cross-checks the attribution method against a number
it did not produce.
Deliverable 3 — is package-scoped validation viable?
The boundary already exists in the data. Package membership is not a key on the object body
(
packages/spec/src/data/object.zod.ts: the package-contribution kind is set viaregisterObject,not on the schema). It is derivable from the object name:
packages/spec/src/kernel/manifest.zod.tsrequires every
object.nameto be the namespace prefix plus a short name, and reserves thesys_prefix for platform objects that apps may reference but never define. So a package-scoped gate needs
no new metadata and no new customer declaration — the boundary is in the name it already writes.
Cross-package reference fraction, over the shipped corpus (
app-showcase22 objects,app-crm6,app-todo1 — 191 reference edges):sys_)By edge kind: lookup 24 (16 same-package / 8 platform), master-detail 7 (all same-package),
flow-node-target 78 (all same-package), permission-grant 73 (61 / 12), sharing-rule-object 7 (all
same-package).
The crux — how wide is the platform dependency? This was the maintainer's own caveat, and it
resolves favourably.
app-showcasenames 3 platform objects directly (sys_user,sys_business_unit,sys_business_unit_member); closed transitively over the platform objects' ownreferencefields that reaches 4 of 44.app-todoreaches 3 of 44;app-crmreaches 0. Thedependency is narrow and shallow — it does not drag in the platform package.
Closure size,
package + platform-closure, projected onto a packaged 420-object tenant:Do the three cross-collection security rules survive it? Yes — and the 38-vs-4 hazard is on a
different collection. PR #7886's phantoms came from narrowing
permissions(a per-writesnapshot holding one set); package-scoping as proposed narrows
objects. Measured onecollection at a time on a synthesized two-package tenant (package A = showcase, package B = the same
corpus re-namespaced, both shipping permission sets), with a positive control so a flat result is
known not to be a blind probe:
permissionsnarrowed to the written item (the #7886 move)objectsscoped to package A,permissionswholeobjectsscoped to package A,permissionswholeobjectsandpermissionsboth scoped to AThe control reproduces the phantom mechanism at this corpus size (8
security-master-detail-ungrantedfindings about package B's details). Every
objects-scoping configuration reaches the whole-stackverdict exactly. A deliberately cross-package master-detail — a shape the corpus scan counts zero
of — also produced an identical verdict under scoping.
Two mechanisms explain it: the rule self-silences when
permissionSetsis empty, and sibling-derivedfindings cancel in the gate's differential. The rules that need siblings need them in
permissions,which package-scoping
objectsdoes not touch.Verdict
Cross-package references are rare (measured: zero) and the platform dependency is narrow (4 of
44), so on this evidence package-scoping is the stronger route: it uses a boundary the customer
already declares, it collapses the realistic N to 6–16% of the tenant's stack, and it manufactures no
false positives in the family that has produced them before.
three standalone example apps that are never installed together. "Zero cross-package references" is
therefore a necessary condition met, not an observation of a real integrated multi-package tenant.
Nothing here measures how often two packages a customer installs together deliberately reference each
other. If that number is what the decision turns on, it needs a corpus this repo does not have.
What ships
scripts/bench/runtime-publish-gate.bench.mtsgains--mode per-ruleand--mode closure, bothreusing the gate's own exported
buildRuntimeWriteSnapshots/runtimeAuthoringRulesForrather thanmirroring the construction.
--mode totaloutput is unchanged.--mode closurenarrows what therules are handed inside that script only; its closure deriver is a measurement over-approximation,
explicitly not a proposed implementation.
Deliverable 3's corpus scan and security probe were throwaway prototypes, as the card permits; their
method is stated above in full (name-prefix boundary,
fields[].referencetransitive expansion,one-collection-at-a-time with a positive control).
No changeset — the only changed file is a bench script in the root, not a published package, and
nothing user-visible changes.
skip-changesetapplied.Gates
Union re-derived with
node scripts/pm/dispatch-gates.mjs(no path list passed) at3171ee40b,which is the final commit:
pnpm check:cross-package-test-inputs— OK (33 self-test cases; 12 packages read outside themselves, all declared)pnpm check:nul-bytes— OK (6285 files, no raw control bytes)pnpm check:type-check-debt— both legs OK. Run per the card's instruction, which the deriverstructurally cannot surface:
scripts/**sits in the ROOT program, defined by exclusion, so nopath literal names it. Full package closure built first as the gate demands. 33 ledger entries
re-measured, 1926 raw errors, none above its recorded number, surplus: none — the root entry did
not move.
Generated by Claude Code