Skip to content

ADR-0025 install-flow design: the effort maintainer ruling 5486840233 assigns the materialize seam to, which has never existed as tracked work #17757

Description

@hotlong

Ungraded and unassigned — domain:*, type and priority are triage's write. Filed to give a standing maintainer ruling a real referent; ⛔ not a request to start it.

Why this card exists

Maintainer ruling 5486840233 (2026-09-01, on #13457), verbatim:

The materialize seam (per-plugin context construction) belongs to the ADR-0025 install-flow design work, ⛔ not to be improvised inside either half.

The triage seat's dedupe run against the open board (581 issues, 2026-09-11T00:26Z) found no such card: ADR-0025 matched 7 open issues, none of them an install-flow design effort — #15213 is ADR-0131 D6 template install modes, #11333 is the parent coordination node. ⇒ the ruling assigned the seam to an effort that is not tracked anywhere, so #17147 could neither be dispatched (it would reverse the ruling) nor held (「无机制可唤醒的卡 ⛔ 不 hold」).

This card is that referent. #17147 is its execution half.

⛔ Deliberately not started — maintainer ruling 2026-09-12, option B

Asked A (open this design front now) / B (say what is true and wait) / C (nothing), the maintainer chose B. What that turns on is a measurement the earlier analysis did not have, taken on 9bd4344e4 across all three repos:

probe result
os plugin install command does not exist — only build / sign / publish
.osplugin loader / dynamic-import of a distributed plugin's entry does not exist
sys_plugin / sys_plugin_version / sys_plugin_installation registry (§3.8) does not exist
what an environment artifact carries per package sys_package_version.manifest_json — metadata. The blob never reaches a runtime
contains_code readers in objectstack 0
per-plugin context construction in cloud none — cloud's role ends at persisting the consent record and copying it onto the artifact envelope

the gate this seam would build has no traffic: a code-bearing package's code cannot execute today, by any path, on any of the three repos. Opening an ADR-level front now would design an install pipeline for a distribution channel with no installer, no loader and no execution. The cheap control was taken instead — see #17147.

What this card owns when it does open

  1. §3.5 steps 4–7 as an actual pipeline: download + verify (signature chain, per-file integrity) → materialize per env/plugin → register (sys_plugin_installation) → load.
  2. The materialize seam itself: per-plugin SecurePluginContext construction, so getService / replaceService and the hook / network / fs surfaces run against that plugin's own registered bag. ⚠️ Two of those four classes (fs, network) have no enforcement surface at all todayenforceFileRead / enforceFileWrite / enforceNetworkRequest are called by nothing, SecurePluginContext included — so wiring the context is necessary and not sufficient.
  3. The hooks vocabulary gap, carried from Phase 1b of #11333: make the registered granted-permission set actually REFUSE — the ADR-0025 materialize seam that gives each plugin its own SecurePluginContext #17147 and unresolved: the grant spells a hook record.beforeInsert, a string that appears nowhere in this repo outside permission examples, docs and tests, while the declarative registry spells the same thing as an object carrying object plus events: [beforeInsert] (spec/src/data/hook.zod.ts). ⚠️ There is a third vocabulary underneath: the grant class says hooks the plugin may register, but SecurePluginContext.hook() has no check — only trigger() does, and its live vocabulary is kernel:ready / auth:configure / metadata:reloaded. Class name, grant vocabulary and enforcement verb are three different things. ⛔ Bridging them is inventing contract semantics.
  4. The unbindable-consent fork, also carried and ⛔ not decided: an entry naming a package the artifact does not carry is reported at warn (grantBinding.unbound). A consented set that binds to nothing is a security control silently absent, so refusing may be right — but refusing needs an ADR-0112 envelope with a new error code, which under [Decision] Clause ② on an UNREGISTERED error code carried by a thrown value: #14552 landed no, #15963 lands yes, and they are the same class #16404 must be registered in packages/spec's ERROR_CODE_LEDGER (another lane) and would re-open the boot-refusal verdict spec: register the 14 remaining door: 'none' (boot-refusal) codes that ship in dist — the rest of the #16404 class after #16449 #16649 ratcheted to zero rows.
  5. §3.6 trust-tier enforcement at load, currently publish-gate-only and documented as such ([text correction · ruled B] manifest.runtime tombstone/describe reads truthfully: publish-gate enforced (cloud), load-side NOT enforced #11330) — the same seam decides whether a declared sandbox / worker tier means anything locally.

The trip-wire that will say when this stops being theoretical

packages/core/src/security/granted-permissions-not-enforced.pin.test.ts (#17753) pins that there are zero production SecurePluginContext construction sites. Whoever opens this design front will turn it red on their first real commit, and its failure message names every text that becomes false at that moment.

Refs

#17147 (execution half) · #11333 (parent) · #13457 / PR #17137 (the registration that landed) · #13458 (Phase 2, Blocked-by: #17147) · #11330 (the trust-tier half, ruled option B on the same surface) · #16404 · #16649 · ADR-0025 · PR #17753 · PR #17756 · objectstack-ai/objectui#9235

Filed while executing #17147 under maintainer ruling 2026-09-12 (option B). ⛔ Ungraded by design.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions