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
{{ message }}
Repository navigation
[Decision] security(objectql): may a hook's handler name bind to a function another package registered (the engine-wide fallback HookSchema.handler declares), or does name resolution stay inside the hook's own package (#21585 option B) #21604
Filing gate: ② a decision only the maintainer can make. It is a security boundary, and the resolution rule is declared in the spec, so changing it is a contract change. Filed by the triage seat (objectstack-wide, seat post #6015, session_01AavokzJ5DndAwitDXvKy4U). It carries option B of the pm:retriage on #21585 (5970562606). #21585 itself is answered A in this round, which closes the install-local door only. ⛔ Not a claim, ⛔ not a dispatch. ⛔ Classes, doors, positions and functions only.
Reader who acts: the maintainer, or the director seat. If the letter is B, domain:engine carries it, and the spec doc moves in the same PR.
packages/objectql/src/hook-binder.ts, resolveHandler (about :321–:322) tries the bundle's own functions, then engine.resolveFunction(name).
The engine's function map is keyed by bare name. The stored owner is not consulted on lookup.
Declared:packages/spec/src/data/hook.zod.ts (about :318), HookSchema.handler's doc, says the name may resolve to "anything engine.registerFunction(name, fn) added".
Pull for cross-package resolution, measured now: zero known writers.
objectstack examples/**: no hook names a string handler. The only string handler is a job's, which resolves within its own bundle.
hotcrm src/**: no hook with a string handler.
Inside packages/**, registerFunction is called only by the engine, the hook binder and the formula stdlib.
Who can reach it: a holder of the metadata-management capability, either by installing a package or by authoring a hook through the metadata door. The open question is whether a package's content, a third-party catalog package above all, should be able to run code it did not ship.
Governing text
HookSchema.handler's doc (above): it declares the engine-wide fallback. So B is a contract change, not a defect fix.
Ruled: 5974477722 · letter B · 2026-10-03T23:13Z
Filing gate: ② a decision only the maintainer can make. It is a security boundary, and the resolution rule is declared in the spec, so changing it is a contract change. Filed by the triage seat (objectstack-wide, seat post #6015,
session_01AavokzJ5DndAwitDXvKy4U). It carries option B of thepm:retriageon #21585 (5970562606). #21585 itself is answered A in this round, which closes the install-local door only. ⛔ Not a claim, ⛔ not a dispatch. ⛔ Classes, doors, positions and functions only.Reader who acts: the maintainer, or the director seat. If the letter is B,
domain:enginecarries it, and the spec doc moves in the same PR.维护者速读
Measured
5970542332, onmain6c5697dffb, through the public door): a package's handler-only hook ran a function that another app registered. This held hot and after a restart. A unit reading on one engine agrees: the resolved function'spackageIdis the other app's.mainb610eabf72:packages/objectql/src/hook-binder.ts,resolveHandler(about:321–:322) tries the bundle's own functions, thenengine.resolveFunction(name).packages/spec/src/data/hook.zod.ts(about:318),HookSchema.handler's doc, says the name may resolve to "anythingengine.registerFunction(name, fn)added".examples/**: no hook names a string handler. The only string handler is a job's, which resolves within its own bundle.src/**: no hook with a string handler.packages/**,registerFunctionis called only by the engine, the hook binder and the formula stdlib.Governing text
HookSchema.handler's doc (above): it declares the engine-wide fallback. So B is a contract change, not a defect fix.5965059068): app bodies stay out of what is not theirs. The same principle, applied to another surface.cross-app function,resolveFunction,owner-scoped,handler fallback→ 1 hit ([finding] os package install accepts a package whose hook uses only the deprecated function-name handler (no body), answers "installed", and the hook never fires: install-local drops it with a server-side warn only #21585, this card's source); ADR none; thread: [finding] os package install accepts a package whose hook uses only the deprecated function-name handler (no body), answers "installed", and the hook never fires: install-local drops it with a server-side warn only #21585.一句话问题
一个应用包的钩子,能不能靠「同名」去执行另一个应用包的代码?
选项 × 真实代价
业务含义直译
四轴(业务立场)
os-decision-facets
推荐:B。 两年后的样子:每个包的代码按包解析,跨包调用都是显式、可审计的引用。参照 Salesforce:托管包的 Apex 类带命名空间前缀,跨包调用要写全名。
回退:A。 只改文档,写明跨包共享是有意的;#21585 的 A 已经堵住本地安装这个入口。
自检: 只看①选 B;②③④ 是否翻转:否。三轴同向。
置信缺口: 我看不到私有客户的多应用组合。一个
defineStack里多个应用共用一组函数,按名字跨包绑定,这种写法在示例里没有,但在客户那里可能存在。这正是 B 的认领要先普查的。常设规则「新门默认否」偏向 A,所以维护者不回字时按 A 处理。裁后执行
not planned关闭。HookSchema.handler的文档改写一句,把跨包共享写成有意的能力(domain:spec,一个小 PR)。pm:queue(domain:engine),并在同一个 PR 里改 spec 声明(作为声明的跨车道路径)。--artifact运行时模块。!、Clause-②: yes (narrowing)、ADR-0087 标记、minor)。