You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Successor-pricing note from PR #6708 (#6285), recorded before this card is dispatched — domain:metadata PM, session session_01W6bLax4KMrSfnE1ydFU8Dw:
EASIER. The runtime authoring gate's call site now gathers and passes deployment context (organizationId + tenancy posture) — this card inherits that plumbing instead of inventing it, and organizationId is exactly the input an object-write gate needs.
Measurements carried over from #6715, which closed as mis-scoped into this card (domain:metadata seat, session session_01W6bLax4KMrSfnE1ydFU8Dw). Recording, not claiming — this is pricing input for whoever takes this card up.
#6715 asked to widen one rule (validateEmptyCombinators) from runtimeTypes: ['flow'] to the other filter-carrying types. It was dispatched with a stop condition, the condition fired, and no code was written. Four results are worth having on this thread:
1. The gate dispatches on flow alone, across the whole rule family. Measured on origin/main: runtimeGatedTypes() returns exactly ['flow'], and all six rules on the runtime-publish surface declare runtimeTypes: ['flow'] (validateStackExpressions, validateEmptyCombinators, validateReferenceIntegrity, validateFlowTriggerReadiness, validateApprovalApprovers, lintFlowPatterns — 6 of 37 total rules reach that door at all). Every other type measures gated-by=(NONE), with errors=0 rulesRun=[]. The only out-of-band gate at that door is ADR-0094's registerAuthoringGate, registered exactly once, on object, by plugin-security — and it judges OWD security posture, not authored filters. So this card is not "one more type for one rule"; it is the whole frontier, which is what its own text already says.
2. The type list in circulation is wrong — seven surfaces, not four.EMPTY_COMBINATOR_SURFACES walks objects, views, pages, dashboards, reports, datasets, apps; all seven are real MetadataTypes with allowRuntimeCreate: true. The "four types" figure that appears in #6715's body and in the registry comment at packages/lint/src/authoring-rules.ts:502-510 undercounts by three.
3. There is a mechanical blocker behind three of those seven.report / dataset / app have no TYPE_TO_STACK_KEY entry (packages/lint/src/runtime-gate.ts:68-78), and authoring-rule-wiring.test.ts:387 fails on any gated type lacking one. So "one line" holds only for the four mapped types; opening the frontier properly means deciding what those three map to, or deciding deliberately that they stay out.
4. The false-positive-budget precondition cannot be paid from this repo's corpus as it stands.#6715's corpus measurement returned 0 would-be-refused across 94 non-flow items in showcase/CRM/todo — but that 0 is weak by construction: these rules are already gating on all types for os validate / os build / os lint, so anything in a config-file corpus is already refused there. The corpus that would actually exercise the question is stored sys_metadata overlay rows, which do not exist in-repo. Whoever takes this card up should plan for where that replay corpus comes from, rather than discovering mid-flight that the in-repo corpus cannot answer it.
One more note that changes this card's stakes rather than its scope: #6710 landed today (PR #6971, 30283263c). The runtime publish gate is now active by default on every kernel, keyed on a declared authoring channel instead of the environmentId proxy — so more topologies reach this door than did yesterday, including the CLI host-config assembly. The frontier this card moves is now wider than when it was filed.
The registry comment at authoring-rules.ts:502-510 was deliberately left untouched by #6715: its stated condition ("once #4463 P2 opens them at the gate") is measurably still unmet — #6710 settled which kernels activate the gate, not which types it dispatches on. It should be flipped by whichever PR actually opens the types, i.e. this one.
Lane note: the landing site is packages/lint/src/authoring-rules.ts — the devx lane's package; metadata-protocol consumes the table via @objectstack/lint/runtime. This seat is not claiming the card.
PM status correction + dispatch ordering (domain:metadata seat, session session_01W6bLax4KMrSfnE1ydFU8Dw). Not dispatched this round, and the reason has changed.
This seat's own lane note was wrong. On 08-09 (comment 5230446731) I wrote that the landing site is packages/lint and that this seat was not claiming the card. That conflated two different things: [finding] validateEmptyCombinators gates the runtime publish path for flow only — the other filter-carrying metadata types reach the same door ungated #6715 measured where one rule's registration lives (packages/lint, devx), but this card's subject is the gate itself extending to object writes, and the maintainer's 2026-08-07 migration ruling put that line squarely on saveMetaItem / promoteDraftForPublish — metadata-protocol, this seat's surface. The lint half is what gets split out under rule 2, not the card.
Why it is still not dispatched this round — a real region conflict, not a blocker.#4717 was dispatched minutes ago and is changing saveMetaItem's response envelope. This card's gate line lands in saveMetaItem / promoteDraftForPublish. Same function. This lane's parallel-authorship authorisation is explicitly "region-disjoint only; same function or same region never in the same batch", so this card follows #4717 rather than riding beside it.
Two pricing inputs that must not be lost when it is taken up (measured by #6715, carried here in comment 5230446731):
The gate dispatches on flow alone across all six rules on the runtime-publish surface — this card is the whole frontier, which its own text already says, and it forbids delivery as a one-line runtimeTypes edit.
The false-positive-budget precondition cannot be paid from this repo's corpus as it stands. The corpus that would exercise the question is stored sys_metadata overlay rows, which do not exist in-repo. Whoever takes this card up should settle where that replay corpus comes from before dispatch, rather than discovering it mid-flight. That is the genuine open item on this card now — not [metadata-core] sys_view_definition 的"活跃行唯一"从未生效——归档视图仍占用 (name, organization_id, owner) 名额 #5839, and not lane ownership.
Also relevant since filing: #6710 landed (30283263c), so more topologies reach this gate than when the card was written, and the registry comment at authoring-rules.ts:502-510 ("once #4463 P2 opens them at the gate") is still measurably unmet — it should be flipped by whichever PR actually opens the types, i.e. this one.
domain:metadata seat — not dispatching, and escalating the one precondition that has blocked this card for six days without being named as a decision. PM session session_01XeQRiAa7vYRVX5Fog7Zby8. ⛔ No label changed, ⛔ not claiming.
What I verified before writing this
The Blocked-by: line in the body is discharged.#4463 closed completed 2026-08-02T22:02:24Z via merged PR #4715. I checked rather than reading the line's presence as state — that exact substitution cost me two wrong reports on other cards earlier today, and this body's "PR #4715 合并前不要派发" is precisely the shape that invites it.
The 2026-08-10 region conflict recorded in comment 5236052336 (#4717 rewriting saveMetaItem's response envelope) is five days stale and is not why this card is sitting.
The real blocker is a decision nobody has been asked to make
From the previous seat's own measurement, carried in 5230446731 and re-stated in 5236052336:
The false-positive-budget precondition cannot be paid from this repo's corpus as it stands. The corpus that would actually exercise the question is stored sys_metadata overlay rows, which do not exist in-repo.
And why the in-repo corpus cannot substitute, which is the sharp part: #6715 measured 0 would-be-refused across 94 non-flow items in showcase/CRM/todo — but that zero is weak by construction. These rules are already gating on all types for os validate / os build / os lint, so anything living in a config-file corpus has already been refused there. A config-file corpus cannot produce a violating row; only a tenant's stored overlay can.
This card's own body makes that budget an acceptance criterion, not a nicety:
上 object 之前需要一批真实租户元数据的回放,证明不会把既有合法 object 判红
and states the stake plainly: object writes are the hottest metadata path in the product (every Studio field edit), so a mistaken 422's blast radius is the tenant's only editing surface.
⇒ There is no dispatch that can satisfy this card's own acceptance criterion today. Sending a dev now buys either a run that stops at the corpus, or — worse — one that pays the budget with the in-repo corpus and reports a green 0 that is green by construction.
The question for you (this is the escalation)
Where does the replay corpus of stored sys_metadata overlay rows come from? Three shapes, and this is a product/data-access call, not a dev's:
Real tenant data — is there a corpus we can lawfully replay against, and who can produce an export?
Synthesised — generate overlay rows that exercise the seven EMPTY_COMBINATOR_SURFACES types. Cheap and available today, but it measures the generator's imagination, not the field.
Ship behind the escape valve — land the gate defaulted off for object with OS_ALLOW_UNLINTED_METADATA_WRITES-shaped opt-in (D4's shape, already ruled on [runtime/metadata] 作者时规则只存在于 CLI:Studio/REST/MCP 的运行时授权面是第四扇门,26 条规则一条不跑——#4409 修完后最大的敞口 #4463), collect real refusals from opted-in environments, then flip the default as a second card. This pays the budget with production traffic instead of a corpus.
My reading, offered as input and not a recommendation to adopt: 3, because it is the only one that measures the actual field without needing a data-access answer first, and because it turns an unbounded precondition into a normal two-step rollout. But it does put a temporarily-declared-but-unenforced gate on object in the interim, which is an ADR-0049 tension worth your eye rather than mine.
Three measured facts that should not be re-derived when this is next taken up
Carried from #6715 via 5230446731, all measured on origin/main, none of them re-verified by me today — treat them as dated evidence, not current state:
The gate dispatches on flow alone across all six runtime-publish rules (6 of 37 rules reach that door). So this card is the whole frontier, and ⛔ must not be delivered as a one-line runtimeTypes edit — its own body says so.
The type list in circulation undercounts by three.EMPTY_COMBINATOR_SURFACES walks seven types (objects, views, pages, dashboards, reports, datasets, apps), not the "four" in the card and in the registry comment at authoring-rules.ts:502-510.
Three of the seven have a mechanical blocker: report / dataset / app have no TYPE_TO_STACK_KEY entry, and authoring-rule-wiring.test.ts fails on any gated type lacking one. So "one line" holds only for the four mapped types; opening the frontier means deciding what those three map to, or deciding deliberately that they stay out.
Also: #6710 landed (30283263c), so the runtime publish gate is now active by default on every kernel rather than keyed on the environmentId proxy — more topologies reach this door than when the card was filed, which widens the frontier this card moves.
⇒ Suggested disposition (triage's call, not mine): pm:queue → needs-user-decision until the corpus question above is answered. A card whose own acceptance criterion is unpayable is not dispatchable, and leaving it pm:queue means it looks workable in every listing and consumes a reader each pass — the failure #8337 has been demonstrating for two days.
Premise verified: #4463 P1 has landed. This card's stated prerequisite is discharged.
⛔ Not a claim, not dispatched — recording a measurement and the two things that still stand between this card and a dispatch.
The measurement
This card is titled "…(#4463 P1 之后)", and I had it parked in this seat's working notes as 「前提待复验」 — for an entire shift, without ever verifying it. Read just now:
So the prerequisite was satisfied two weeks before the shift in which I parked this card as premise-unverified. The block was mine, not the repo's. Recorded as an error rather than quietly fixed: this card sat in pm:queue, dispatchable-in-principle, and was reported to the maintainer as part of a queue of zero. Full account at #63675308000846.
What still stands before dispatch — two items, neither of them the premise
1. The P2 scope is only 「建议」 in #4463, not ruled.#4463's batching note gives P2 as:
The advisory-findings-in-response half is #4463's D3, and D3 was written as a recommendation (「建议」) alongside D1/D2/D4 — P1 landed without needing the advisory limb settled. Extending to all runtime-safe rules also re-opens D2: #4463 recommended option (c) "首期只按被写 item 的类型跑相关规则族" to start and option (a) "写入时从 registry 构造 stack 视图快照,跑全套" to finish — and this card is the (a) finish, whose per-save cost #4463 explicitly said needs measuring rather than assuming. That measurement has not been taken.
2. The companion objectui card #4463 requires may not exist.⚠️ Not checked. It is a prerequisite of the P2 scope by #4463's own text, and a rendering half with no card is the same evaporation shape that cost #9029 its home.
Also worth flagging for whoever takes it
packages/metadata-protocol/src/protocol.ts is a hot file and currently carries two in-flight claims this round (#9066recordCommit, #9009getEffectiveLock). A third concurrent editor sits at the standing cap, and this card's surface is far larger than either — region clearance would have to come from both PRs' actual changed ranges.
⛔ Labels and assignee untouched; the card remains pm:queue and unclaimed.
{
"issue": 4716,
"status": "done",
"branch": "claude/issue-4716-lazy-deps-tripwire-object-leg",
"pr": "https://github.com/objectstack-ai/objectstack/pull/9295",
"premise_still_valid": true,
"summary": "Implemented the one ruled prerequisite and nothing else: runtime-lazy-deps.test.ts now gates an OBJECT write carrying a json_schema validation, in-process and in both spawned dist entries, so the assertion is as wide as its own docblock prose. Added a spawned positive control proving the require-cache probe really sees ajv + ajv-formats load when validateRuleCompilability judges that same body — a clean require-cache walk proves nothing until it has been shown to report dirty. Every PM 机制假设 was re-measured on this branch and all four held; none was falsified. Test-only: no rule, no AUTHORING_RULES entry, no runtimeTypes, no gate dispatch, nothing that changes what the gate accepts or refuses; the false-positive-budget precondition was not approached.",
"tests": "All at head commit 0f405abc1 (branch built from origin/main @ fab693bee). (1) MEASUREMENT, spawned-process require.cache walk over built dist: import runtime.cjs -> 0/0; import full index.cjs barrel -> 0/0; RUN gate on flow write -> 0/0; RUN gate on OBJECT write carrying a json_schema validation -> 0/0; RUN validateRuleCompilability over that same object body -> ajv 63 modules + ajv-formats 3 modules. NON-VACUITY of the probe: that last run returns exactly 1 finding, validation-rule-json-schema-uncompilable ('schema is invalid: data/required must be array, ...'), cold 56.4 ms vs warm 11.5 ms. (2) REVERSE VERIFICATION, direction RED as predicted: ablated validateRuleCompilability to surfaces CLI_AND_RUNTIME + runtimeTypes ['object'] and REBUILT the package (the spawned legs read dist/, so an unrebuilt ablation would have run pre-mutation code and stayed green). Old guard from origin/main on that tree: 4/4 GREEN while ajv was demonstrably loading onto the boot path — the blind spot measured, not argued. New guard on the same tree: 3 of 6 legs RED (spawned CJS, spawned ESM, in-process object leg), each naming ajv; the flow leg stayed green, which is exactly why flow-only was blind. Ablation reverted, package REBUILT, and the artifact re-proved clean: runtimeAuthoringRulesFor('object') back to [validatePresetComparands, validateSecurityPosture], git diff HEAD empty. (3) SUITES: pnpm --filter @objectstack/lint test -> 73 files / 2067 tests passed; pnpm --filter @objectstack/lint typecheck -> tsc --noEmit clean; the guard file itself 6 passed (was 4). (4) GATE UNION re-derived at the final path set with node scripts/pm/dispatch-gates.mjs (not inherited from the prompt) and run at 0f405abc1, all green: check:nul-bytes (6066 files, no control bytes), check:cross-package-test-inputs, check:engine-double-contract (315 pinned / 133 debt / 2 exempt, unchanged), check:where-matcher (251 matchers, 0 new), check:query-options-erasure (baseline unchanged, no files added), check:type-check-coverage, scripts/docs-audit/check-affected-docs.mjs. check:type-check-debt's ratchet needs the whole workspace closure built; instead its subject was checked directly by reproducing its test-inclusive project for @objectstack/lint (package tsconfig with the test excludes dropped) — the edited file contributes 0 tsc diagnostics, so the ledgered count cannot drift up from this change. No TEST_DEBT entry raised or touched.",
"open_questions": [],
"out_of_scope_findings": []
}
Notes the JSON cannot carry
Every PM 机制假设 re-measured; all four held, none falsified.
assumption
re-measured on this branch
ajv still loads on an object-write snapshot carrying a json_schema validation
HOLDS — ajv 63 modules + ajv-formats 3, spawned require.cache walk, 1 finding, cold 56.4 ms / warm 11.5 ms
the load is triggered by the WRITTEN TYPE, not the rule set
HOLDS — and it is now the load-bearing reason the new leg exists; the flow leg stayed green under the ablation that reddened all three object legs
runtimeGatedTypes() returns 8 types including object; 11 of 41 rules on runtime-publish
HOLDS exactly — book, dashboard, flow, object, page, permission, seed, view; 11/41. The two rules gating object today are validatePresetComparands + validateSecurityPosture
report/dataset/app have no TYPE_TO_STACK_KEY entry
HOLDS — not touched; the table was not edited
One deviation from the dispatch text, flagged rather than silently taken. The prompt said "Changeset per repo rules". The repo rule for this PR is no changeset: lint.yml:637 states that a PR which "releases nothing" is "the textbook skip-changeset case", and AGENTS.md:912 asks for a changeset on feature work only. This PR edits one test file and ships no published code. I wrote a changeset first, then removed it and applied skip-changeset instead. Labels read back after bots settled: size/m, tests, skip-changeset (the write was a union over what was already there, not a bare set).
Part of #4716, never Fixes — the card's own acceptance criterion (the false-positive budget against a stored sys_metadata replay corpus) is unpaid and untouched, and the card must stay open.
Two fixture properties a future editor can break silently, so both are guarded in-file rather than left to prose. The object body must keep tripping a rule that gates object today (else the dep probe is vacuous — asserted as rulesRun.length > 0 plus the filter-preset-comparand finding), and its schema must stay one ajv refuses (else the negative leg degrades into "a body with nothing in it loads nothing" — that is what the positive control fails on, with a message saying to restore the schema rather than delete the test).
Adjudication record (maintainer, 2026-08-18, PM chat with the skills seat, session session_01WswfK2yNYT9hNnMH6TzAwL — analysis delivered in chat over this thread's full record, ruling given directly). Verbatim, untranslated: 「objectstack cloud 还没有正式上线,简化开发。」then, on the simplification package as proposed: 「同意」.
Q1 (comment 5328455567) = B, exemption — with option A ruled structurally unavailable, not declined: objectstack cloud has not launched, so no real tenant exists whose sys_metadata overlay rows could be exported. That fact both closes route A and explains why the corpus was unfindable in-repo — it has not been produced by reality yet. The false-positive budget is exempted on today's measurement (0 refusals / 75 real object declarations across two authoring lineages, 0 phantoms after the instrument fix, non-vacuity proven by 6 synthetic violations refusing correctly), with the lower-bound caveat stated in as many words: every measured population is authored config-file metadata, the cleanest possible input. Post-launch follow-up expectation, not a gate: when the first real tenants exist, a replay of stored overlay rows is run as an after-the-fact audit of this exemption.
Q2 dissolves by scope: this card's operative scope is the 5 gating rules of RUNTIME_OBJECT_WRITES_P2 only (the option-D arithmetic recorded in comment 5328455567). The 6 advisory-only rules do not ride — the ~8-advisories-per-write designer noise never materialises, and advisory UX becomes separate, non-blocking work.
Split: the full runtime-safe snapshot half (RUNTIME_NEEDS_FULL_SNAPSHOT, the measured expensive half) leaves this card → filed as its own card (see follow-up issue filed today referencing this comment). The pre-existing linear cost of the shipped gate (33.4 ms @ 21 objects → 506 ms @ 420 objects per flow publish, measured in comment 5309093362) is filed as its own finding — it exists before and independent of this card.
Label transition in the same stroke: needs-user-decision → pm:queue, unassigned — the domain:metadata seat dispatches at the narrowed scope (5 gating rules onto the object write door; lazy-deps tripwire prerequisite already landed via PR #9295; false-positive budget exempted per above).
Activity
hotlong commentedon Aug 7, 2026
迁移:
domain:engine-core→domain:metadata(维护者 2026-08-07 批准拆分;座位贴 #6367,SKILL PR #6370)。FLAG 裁定随迁:运行时授权门 P2 的门线落saveMetaItem/promoteDraftForPublish(metadata-protocol 写路径);规则集与 surface 注解的 lint 半边(spec-tooling)在派发时按 rule 2 contract-first 拆出,不整卡跨席。分诊会话:session_01BickTBKm2JYSNnrtPT8ysa。Generated by Claude Code
os-zhuang commentedon Aug 8, 2026
Successor-pricing note from PR #6708 (#6285), recorded before this card is dispatched —
domain:metadataPM, sessionsession_01W6bLax4KMrSfnE1ydFU8Dw:organizationId+ tenancy posture) — this card inherits that plumbing instead of inventing it, andorganizationIdis exactly the input an object-write gate needs.AUTHORING_RULESbecause Q3=A rejects CLI-side judging for that rule. A runtime-safe rule snapshot (this card's second half) belongs inAUTHORING_RULESproper.environmentId === undefinedhost-config topologies) — read it before scoping.(Still queued behind the engine-core seat's #5839 claim; unchanged.)
Generated by Claude Code
os-zhuang commentedon Aug 9, 2026
Measurements carried over from #6715, which closed as mis-scoped into this card (
domain:metadataseat, sessionsession_01W6bLax4KMrSfnE1ydFU8Dw). Recording, not claiming — this is pricing input for whoever takes this card up.#6715 asked to widen one rule (
validateEmptyCombinators) fromruntimeTypes: ['flow']to the other filter-carrying types. It was dispatched with a stop condition, the condition fired, and no code was written. Four results are worth having on this thread:1. The gate dispatches on
flowalone, across the whole rule family. Measured onorigin/main:runtimeGatedTypes()returns exactly['flow'], and all six rules on the runtime-publish surface declareruntimeTypes: ['flow'](validateStackExpressions,validateEmptyCombinators,validateReferenceIntegrity,validateFlowTriggerReadiness,validateApprovalApprovers,lintFlowPatterns— 6 of 37 total rules reach that door at all). Every other type measuresgated-by=(NONE), witherrors=0 rulesRun=[]. The only out-of-band gate at that door is ADR-0094'sregisterAuthoringGate, registered exactly once, onobject, by plugin-security — and it judges OWD security posture, not authored filters. So this card is not "one more type for one rule"; it is the whole frontier, which is what its own text already says.2. The type list in circulation is wrong — seven surfaces, not four.
EMPTY_COMBINATOR_SURFACESwalks objects, views, pages, dashboards, reports, datasets, apps; all seven are realMetadataTypes withallowRuntimeCreate: true. The "four types" figure that appears in #6715's body and in the registry comment atpackages/lint/src/authoring-rules.ts:502-510undercounts by three.3. There is a mechanical blocker behind three of those seven.
report/dataset/apphave noTYPE_TO_STACK_KEYentry (packages/lint/src/runtime-gate.ts:68-78), andauthoring-rule-wiring.test.ts:387fails on any gated type lacking one. So "one line" holds only for the four mapped types; opening the frontier properly means deciding what those three map to, or deciding deliberately that they stay out.4. The false-positive-budget precondition cannot be paid from this repo's corpus as it stands. #6715's corpus measurement returned 0 would-be-refused across 94 non-
flowitems in showcase/CRM/todo — but that 0 is weak by construction: these rules are alreadygatingon all types foros validate/os build/os lint, so anything in a config-file corpus is already refused there. The corpus that would actually exercise the question is storedsys_metadataoverlay rows, which do not exist in-repo. Whoever takes this card up should plan for where that replay corpus comes from, rather than discovering mid-flight that the in-repo corpus cannot answer it.One more note that changes this card's stakes rather than its scope: #6710 landed today (PR #6971,
30283263c). The runtime publish gate is now active by default on every kernel, keyed on a declared authoring channel instead of theenvironmentIdproxy — so more topologies reach this door than did yesterday, including the CLI host-config assembly. The frontier this card moves is now wider than when it was filed.The registry comment at
authoring-rules.ts:502-510was deliberately left untouched by #6715: its stated condition ("once #4463 P2 opens them at the gate") is measurably still unmet — #6710 settled which kernels activate the gate, not which types it dispatches on. It should be flipped by whichever PR actually opens the types, i.e. this one.Lane note: the landing site is
packages/lint/src/authoring-rules.ts— the devx lane's package;metadata-protocolconsumes the table via@objectstack/lint/runtime. This seat is not claiming the card.Generated by Claude Code
os-zhuang commentedon Aug 10, 2026
PM status correction + dispatch ordering (
domain:metadataseat, sessionsession_01W6bLax4KMrSfnE1ydFU8Dw). Not dispatched this round, and the reason has changed.Correcting two things this seat recorded wrongly.
sys_view_definition的"活跃行唯一"从未生效——归档视图仍占用 (name, organization_id, owner) 名额 #5839 blocker" was never real during this term. This card (and [P2/P3] 运行时授权门的 advisory findings 要进响应并被 Studio 渲染 + docs「the gate」补第四列(#4463 收尾) #4717) carried "still queued behind [metadata-core]sys_view_definition的"活跃行唯一"从未生效——归档视图仍占用 (name, organization_id, owner) 名额 #5839", including in a comment this seat wrote on 08-08. [metadata-core]sys_view_definition的"活跃行唯一"从未生效——归档视图仍占用 (name, organization_id, owner) 名额 #5839 closed as completed on 2026-08-07T17:56:45Z — before this seat was seated. It was inherited as a sentence and repeated without checking whether its precondition still held.packages/lintand that this seat was not claiming the card. That conflated two different things: [finding]validateEmptyCombinatorsgates the runtime publish path forflowonly — the other filter-carrying metadata types reach the same door ungated #6715 measured where one rule's registration lives (packages/lint, devx), but this card's subject is the gate itself extending toobjectwrites, and the maintainer's 2026-08-07 migration ruling put that line squarely onsaveMetaItem/promoteDraftForPublish— metadata-protocol, this seat's surface. The lint half is what gets split out under rule 2, not the card.Why it is still not dispatched this round — a real region conflict, not a blocker. #4717 was dispatched minutes ago and is changing
saveMetaItem's response envelope. This card's gate line lands insaveMetaItem/promoteDraftForPublish. Same function. This lane's parallel-authorship authorisation is explicitly "region-disjoint only; same function or same region never in the same batch", so this card follows #4717 rather than riding beside it.Two pricing inputs that must not be lost when it is taken up (measured by #6715, carried here in comment 5230446731):
flowalone across all six rules on the runtime-publish surface — this card is the whole frontier, which its own text already says, and it forbids delivery as a one-lineruntimeTypesedit.sys_metadataoverlay rows, which do not exist in-repo. Whoever takes this card up should settle where that replay corpus comes from before dispatch, rather than discovering it mid-flight. That is the genuine open item on this card now — not [metadata-core]sys_view_definition的"活跃行唯一"从未生效——归档视图仍占用 (name, organization_id, owner) 名额 #5839, and not lane ownership.Also relevant since filing: #6710 landed (
30283263c), so more topologies reach this gate than when the card was written, and the registry comment atauthoring-rules.ts:502-510("once #4463 P2 opens them at the gate") is still measurably unmet — it should be flipped by whichever PR actually opens the types, i.e. this one.Generated by Claude Code
hotlong commentedon Aug 15, 2026
domain:metadataseat — not dispatching, and escalating the one precondition that has blocked this card for six days without being named as a decision. PM sessionsession_01XeQRiAa7vYRVX5Fog7Zby8. ⛔ No label changed, ⛔ not claiming.What I verified before writing this
The
Blocked-by:line in the body is discharged. #4463 closedcompleted2026-08-02T22:02:24Z via merged PR #4715. I checked rather than reading the line's presence as state — that exact substitution cost me two wrong reports on other cards earlier today, and this body's "PR #4715 合并前不要派发" is precisely the shape that invites it.The 2026-08-10 region conflict recorded in comment
5236052336(#4717 rewritingsaveMetaItem's response envelope) is five days stale and is not why this card is sitting.The real blocker is a decision nobody has been asked to make
From the previous seat's own measurement, carried in
5230446731and re-stated in5236052336:And why the in-repo corpus cannot substitute, which is the sharp part: #6715 measured 0 would-be-refused across 94 non-
flowitems in showcase/CRM/todo — but that zero is weak by construction. These rules are alreadygatingon all types foros validate/os build/os lint, so anything living in a config-file corpus has already been refused there. A config-file corpus cannot produce a violating row; only a tenant's stored overlay can.This card's own body makes that budget an acceptance criterion, not a nicety:
and states the stake plainly:
objectwrites are the hottest metadata path in the product (every Studio field edit), so a mistaken 422's blast radius is the tenant's only editing surface.⇒ There is no dispatch that can satisfy this card's own acceptance criterion today. Sending a dev now buys either a run that stops at the corpus, or — worse — one that pays the budget with the in-repo corpus and reports a green
0that is green by construction.The question for you (this is the escalation)
Where does the replay corpus of stored
sys_metadataoverlay rows come from? Three shapes, and this is a product/data-access call, not a dev's:EMPTY_COMBINATOR_SURFACEStypes. Cheap and available today, but it measures the generator's imagination, not the field.objectwithOS_ALLOW_UNLINTED_METADATA_WRITES-shaped opt-in (D4's shape, already ruled on [runtime/metadata] 作者时规则只存在于 CLI:Studio/REST/MCP 的运行时授权面是第四扇门,26 条规则一条不跑——#4409 修完后最大的敞口 #4463), collect real refusals from opted-in environments, then flip the default as a second card. This pays the budget with production traffic instead of a corpus.My reading, offered as input and not a recommendation to adopt: 3, because it is the only one that measures the actual field without needing a data-access answer first, and because it turns an unbounded precondition into a normal two-step rollout. But it does put a temporarily-declared-but-unenforced gate on
objectin the interim, which is an ADR-0049 tension worth your eye rather than mine.Three measured facts that should not be re-derived when this is next taken up
Carried from #6715 via
5230446731, all measured onorigin/main, none of them re-verified by me today — treat them as dated evidence, not current state:flowalone across all six runtime-publish rules (6 of 37 rules reach that door). So this card is the whole frontier, and ⛔ must not be delivered as a one-lineruntimeTypesedit — its own body says so.EMPTY_COMBINATOR_SURFACESwalks seven types (objects, views, pages, dashboards, reports, datasets, apps), not the "four" in the card and in the registry comment atauthoring-rules.ts:502-510.report/dataset/apphave noTYPE_TO_STACK_KEYentry, andauthoring-rule-wiring.test.tsfails on any gated type lacking one. So "one line" holds only for the four mapped types; opening the frontier means deciding what those three map to, or deciding deliberately that they stay out.Also: #6710 landed (
30283263c), so the runtime publish gate is now active by default on every kernel rather than keyed on theenvironmentIdproxy — more topologies reach this door than when the card was filed, which widens the frontier this card moves.⇒ Suggested disposition (triage's call, not mine):
pm:queue→needs-user-decisionuntil the corpus question above is answered. A card whose own acceptance criterion is unpayable is not dispatchable, and leaving itpm:queuemeans it looks workable in every listing and consumes a reader each pass — the failure #8337 has been demonstrating for two days.Generated by Claude Code
os-zhuang commentedon Aug 16, 2026
Premise verified: #4463 P1 has landed. This card's stated prerequisite is discharged.
⛔ Not a claim, not dispatched — recording a measurement and the two things that still stand between this card and a dispatch.
The measurement
This card is titled "…(#4463 P1 之后)", and I had it parked in this seat's working notes as 「前提待复验」 — for an entire shift, without ever verifying it. Read just now:
So the prerequisite was satisfied two weeks before the shift in which I parked this card as premise-unverified. The block was mine, not the repo's. Recorded as an error rather than quietly fixed: this card sat in
pm:queue, dispatchable-in-principle, and was reported to the maintainer as part of a queue of zero. Full account at #63675308000846.What still stands before dispatch — two items, neither of them the premise
1. The P2 scope is only 「建议」 in #4463, not ruled. #4463's batching note gives P2 as:
The advisory-findings-in-response half is #4463's D3, and D3 was written as a recommendation (「建议」) alongside D1/D2/D4 — P1 landed without needing the advisory limb settled. Extending to all runtime-safe rules also re-opens D2: #4463 recommended option (c) "首期只按被写 item 的类型跑相关规则族" to start and option (a) "写入时从 registry 构造 stack 视图快照,跑全套" to finish — and this card is the (a) finish, whose per-save cost #4463 explicitly said needs measuring rather than assuming. That measurement has not been taken.
2. The companion⚠️ Not checked. It is a prerequisite of the P2 scope by #4463's own text, and a rendering half with no card is the same evaporation shape that cost #9029 its home.
objectuicard #4463 requires may not exist.Also worth flagging for whoever takes it
packages/metadata-protocol/src/protocol.tsis a hot file and currently carries two in-flight claims this round (#9066recordCommit, #9009getEffectiveLock). A third concurrent editor sits at the standing cap, and this card's surface is far larger than either — region clearance would have to come from both PRs' actual changed ranges.⛔ Labels and assignee untouched; the card remains
pm:queueand unclaimed.Generated by Claude Code
10 remaining items
os-zhuang commentedon Aug 17, 2026
{ "issue": 4716, "status": "done", "branch": "claude/issue-4716-lazy-deps-tripwire-object-leg", "pr": "https://github.com/objectstack-ai/objectstack/pull/9295", "premise_still_valid": true, "summary": "Implemented the one ruled prerequisite and nothing else: runtime-lazy-deps.test.ts now gates an OBJECT write carrying a json_schema validation, in-process and in both spawned dist entries, so the assertion is as wide as its own docblock prose. Added a spawned positive control proving the require-cache probe really sees ajv + ajv-formats load when validateRuleCompilability judges that same body — a clean require-cache walk proves nothing until it has been shown to report dirty. Every PM 机制假设 was re-measured on this branch and all four held; none was falsified. Test-only: no rule, no AUTHORING_RULES entry, no runtimeTypes, no gate dispatch, nothing that changes what the gate accepts or refuses; the false-positive-budget precondition was not approached.", "tests": "All at head commit 0f405abc1 (branch built from origin/main @ fab693bee). (1) MEASUREMENT, spawned-process require.cache walk over built dist: import runtime.cjs -> 0/0; import full index.cjs barrel -> 0/0; RUN gate on flow write -> 0/0; RUN gate on OBJECT write carrying a json_schema validation -> 0/0; RUN validateRuleCompilability over that same object body -> ajv 63 modules + ajv-formats 3 modules. NON-VACUITY of the probe: that last run returns exactly 1 finding, validation-rule-json-schema-uncompilable ('schema is invalid: data/required must be array, ...'), cold 56.4 ms vs warm 11.5 ms. (2) REVERSE VERIFICATION, direction RED as predicted: ablated validateRuleCompilability to surfaces CLI_AND_RUNTIME + runtimeTypes ['object'] and REBUILT the package (the spawned legs read dist/, so an unrebuilt ablation would have run pre-mutation code and stayed green). Old guard from origin/main on that tree: 4/4 GREEN while ajv was demonstrably loading onto the boot path — the blind spot measured, not argued. New guard on the same tree: 3 of 6 legs RED (spawned CJS, spawned ESM, in-process object leg), each naming ajv; the flow leg stayed green, which is exactly why flow-only was blind. Ablation reverted, package REBUILT, and the artifact re-proved clean: runtimeAuthoringRulesFor('object') back to [validatePresetComparands, validateSecurityPosture], git diff HEAD empty. (3) SUITES: pnpm --filter @objectstack/lint test -> 73 files / 2067 tests passed; pnpm --filter @objectstack/lint typecheck -> tsc --noEmit clean; the guard file itself 6 passed (was 4). (4) GATE UNION re-derived at the final path set with node scripts/pm/dispatch-gates.mjs (not inherited from the prompt) and run at 0f405abc1, all green: check:nul-bytes (6066 files, no control bytes), check:cross-package-test-inputs, check:engine-double-contract (315 pinned / 133 debt / 2 exempt, unchanged), check:where-matcher (251 matchers, 0 new), check:query-options-erasure (baseline unchanged, no files added), check:type-check-coverage, scripts/docs-audit/check-affected-docs.mjs. check:type-check-debt's ratchet needs the whole workspace closure built; instead its subject was checked directly by reproducing its test-inclusive project for @objectstack/lint (package tsconfig with the test excludes dropped) — the edited file contributes 0 tsc diagnostics, so the ledgered count cannot drift up from this change. No TEST_DEBT entry raised or touched.", "open_questions": [], "out_of_scope_findings": [] }Notes the JSON cannot carry
Every PM 机制假设 re-measured; all four held, none falsified.
json_schemavalidationrequire.cachewalk, 1 finding, cold 56.4 ms / warm 11.5 msruntimeGatedTypes()returns 8 types includingobject; 11 of 41 rules onruntime-publishbook, dashboard, flow, object, page, permission, seed, view; 11/41. The two rules gatingobjecttoday arevalidatePresetComparands+validateSecurityPosturereport/dataset/apphave noTYPE_TO_STACK_KEYentryOne deviation from the dispatch text, flagged rather than silently taken. The prompt said "Changeset per repo rules". The repo rule for this PR is no changeset:
lint.yml:637states that a PR which "releases nothing" is "the textbookskip-changesetcase", and AGENTS.md:912 asks for a changeset on feature work only. This PR edits one test file and ships no published code. I wrote a changeset first, then removed it and appliedskip-changesetinstead. Labels read back after bots settled:size/m,tests,skip-changeset(the write was a union over what was already there, not a bare set).Part of #4716, neverFixes— the card's own acceptance criterion (the false-positive budget against a storedsys_metadatareplay corpus) is unpaid and untouched, and the card must stay open.Two fixture properties a future editor can break silently, so both are guarded in-file rather than left to prose. The object body must keep tripping a rule that gates
objecttoday (else the dep probe is vacuous — asserted asrulesRun.length > 0plus thefilter-preset-comparandfinding), and itsschemamust stay one ajv refuses (else the negative leg degrades into "a body with nothing in it loads nothing" — that is what the positive control fails on, with a message saying to restore the schema rather than delete the test).Generated by Claude Code
searchableFieldsandsort) are CLI-only — the reference-integrity suite dispatches at the runtime publish gate forflowalone, so a Studio/MCPviewwrite gets neither #9313os-support-ai commentedon Aug 18, 2026
Adjudication record (maintainer, 2026-08-18, PM chat with the skills seat, session
session_01WswfK2yNYT9hNnMH6TzAwL— analysis delivered in chat over this thread's full record, ruling given directly). Verbatim, untranslated: 「objectstack cloud 还没有正式上线,简化开发。」then, on the simplification package as proposed: 「同意」.Q1 (comment 5328455567) = B, exemption — with option A ruled structurally unavailable, not declined: objectstack cloud has not launched, so no real tenant exists whose
sys_metadataoverlay rows could be exported. That fact both closes route A and explains why the corpus was unfindable in-repo — it has not been produced by reality yet. The false-positive budget is exempted on today's measurement (0 refusals / 75 real object declarations across two authoring lineages, 0 phantoms after the instrument fix, non-vacuity proven by 6 synthetic violations refusing correctly), with the lower-bound caveat stated in as many words: every measured population is authored config-file metadata, the cleanest possible input. Post-launch follow-up expectation, not a gate: when the first real tenants exist, a replay of stored overlay rows is run as an after-the-fact audit of this exemption.Q2 dissolves by scope: this card's operative scope is the 5 gating rules of
RUNTIME_OBJECT_WRITES_P2only (the option-D arithmetic recorded in comment 5328455567). The 6 advisory-only rules do not ride — the ~8-advisories-per-write designer noise never materialises, and advisory UX becomes separate, non-blocking work.Split: the full runtime-safe snapshot half (
RUNTIME_NEEDS_FULL_SNAPSHOT, the measured expensive half) leaves this card → filed as its own card (see follow-up issue filed today referencing this comment). The pre-existing linear cost of the shipped gate (33.4 ms @ 21 objects → 506 ms @ 420 objects per flow publish, measured in comment 5309093362) is filed as its own finding — it exists before and independent of this card.Label transition in the same stroke:
needs-user-decision→pm:queue, unassigned — thedomain:metadataseat dispatches at the narrowed scope (5 gating rules onto the object write door; lazy-deps tripwire prerequisite already landed via PR #9295; false-positive budget exempted per above).Generated by Claude Code
test(lint): give the runtime lazy-deps guard an object-write leg (obj…
feat(lint): the five gating object rules cross the runtime publish ga…
docs(validating-metadata): the four-door table records the object run…
docs(bench): record the object door's cost on BOTH sides of objectsta…
chore(lint): changeset, and re-point the #4716 Q2 fence at the object…
fix(lint): hold `skill` out of the runtime-create wiring, and declare…
spec(lint): wire the six inert runtime-create doors — action / hook /…
docs(lint): re-anchor the five dead tracker citations in authoring-ru…
feat(lint)!: validateComponentProps and validateComponentTypes run on…