Repository navigation
[finding] @objectstack/organizations is an out-of-repo enterprise runtime with no row in PLATFORM_CAPABILITY_PROVIDERS — the roster that already answers #10921's question for every other one #11263
Description
Activity
Finding concentration round (triage seat, session
session_01Kktexqp6uVuFMztvvTMf3V, 2026-08-24, maintainer-invoked): promoted →pm:queue+domain:spec, Task (S). Add the@objectstack/organizationsrow toPLATFORM_CAPABILITY_PROVIDERS(edition: enterprise, provenance note per the roster's own shape); the drift test (serve-capability-vocabulary.test.ts) pins it. This is the roster #10921 asked for, answering the same question for the one package missing from it.
Generated by Claude Code
Claim: spec-lane PM dispatch (wave 10).
Session:session_01T9cDbY2NBiVJWYx3BpWfH2(PM; dev subagent runs inside this session's container).
Branch:claude/issue-11263-organizations-capability-roster
Worktree:../objectstack-issue-11263(dev-created, per-task).
Domain:domain:spec@ objectstack.
File surface:packages/spec/src/kernel/platform-capabilities.ts+serve-capability-vocabulary.test.ts+ any generated artifacts the gates demand. Disjoint from in-flight #11256 (page.zod.ts) and #11269 (component.zod.tsprose).
Container & model: os-dev subagent, fable tier (claude-fable-5— clause-② at dispatch: the card's own measurement shows the roster's token-keyed space cannot hold@objectstack/organizations, so ANY fix widens public surface — minted token, widened key space, or a sibling posture-keyed export). Fuse read at collect per four-step.
Clause-②: YES at dispatch —needs:contract-reviewhung on this card in the claim stroke; the PR hangs its own carrier at creation; both cleared same-stroke only after the PM's fable review of the actual diff.
Serial constraints: fable slot (one fable dev at a time) — this is the sole fable in flight. Note for the dev: triage's gloss ("add the row") and the card's structural objection (key space has nowhere to put it) conflict — the card is measure-first; if the minimal by-construction shape cannot avoid redefining how tenancy posture relates to therequirescapability vocabulary, STOP and report for decision-boxing rather than minting semantics.
Generated by Claude Code
{ "issue": 11263, "outcome": "PR", "status": "done", "pr": 11613, "pr_url": "https://github.com/objectstack-ai/objectstack/pull/11613", "branch": "claude/issue-11263-organizations-capability-roster", "head_sha": "e239aa5fe4d807724da894ee17b639cf57fd8a3a", "premise_still_valid": true, "shape_chosen": "Sibling package-name-keyed provenance export PLATFORM_PLUGIN_WIRED_RUNTIMES (+ row type PlatformPluginWiredRuntime) in packages/spec/src/kernel/platform-capabilities.ts, population of two (organizations + security-enterprise), edition typed Exclude of CapabilityEdition minus open so a mis-filed open row cannot compile, note required. Rejected by measurement: minting an organizations requires-token (would enter the 1:1 vocabulary and flip requires:['organizations'] from authoring rejection to accepted-but-resolved-by-nothing) and widening the token map's key space (breaks the 1:1 drift invariant, makes classifyRequiredCapability treat a non-token as a provider hit). Posture-keyed sibling also rejected: fits only one of the two members and encodes resolution semantics.", "clause2_selfassessment": "Public surface widened by exactly two exported symbols (one const, one interface) on @objectstack/spec, additive-only (api-surface diff is exactly those two entries). No capability token minted, no key-space widening, no change to what requires means, no posture-to-token semantics — load conditions stay in the runtimes, recorded here only as prose provenance. STOP condition (redefining tenancy-posture vs requires vocabulary) not met, so no stop. Drift wiring: CLI drift test gains 4 pins (organizations row enterprise; every enterprise-edition provider package must have a roster row — derived, covers the next enterprise token on arrival; edition agreement wherever both rosters name one package; roster packages never in serve CAPABILITY_PROVIDERS), spec-side test gains 5 shape invariants incl. keys-disjoint-from-vocabulary. Ablation proved the two load-bearing pins fail in the predicted direction (2 failed | 10 passed on the mutant, 12/12 restored), both legs spec-rebuilt with dist preflight (markers present in 8 built files; absent from all 209 on restore) and anchored on-disk confirmation.", "gates": [ {"name": "spec build", "verdict": "exit 0 — dist .build-input-hash written"}, {"name": "spec test", "verdict": "Test Files 420 passed (420) · Tests 11218 passed (11218)"}, {"name": "spec typecheck", "verdict": "check:test-typecheck: OK — test layer compiles; exit 0"}, {"name": "spec check:generated", "verdict": "after --fix of the 2 proved stale: All 14 generated artifacts are up to date"}, {"name": "cli serve-capability-vocabulary.test.ts", "verdict": "Tests 12 passed (12)"}, {"name": "cli typecheck", "verdict": "exit 0"}, {"name": "check:nul-bytes", "verdict": "exit 0"}, {"name": "check:changeset-gate-self-tests", "verdict": "exit 0"}, {"name": "check:objectui-changeset", "verdict": "exit 0"}, {"name": "check-adr-0087-registration", "verdict": "exit 0 (minor, not breaking — no marker owed)"}, {"name": "check-changeset-no-major", "verdict": "exit 0"}, {"name": "check-empty-changeset", "verdict": "exit 0"}, {"name": "release-rehearsal-clone --self-test", "verdict": "exit 0"}, {"name": "check:merge-driver", "verdict": "exit 0"}, {"name": "check-dev-prereqs", "verdict": "exit 0 after workspace build (first run: documented unbuilt-workspace precondition)"}, {"name": "check-ci-filter-parity", "verdict": "exit 0"}, {"name": "check:cross-package-test-inputs", "verdict": "exit 0"}, {"name": "check:slot-lookup", "verdict": "exit 0"}, {"name": "check:spec-parsed-alias", "verdict": "exit 0"}, {"name": "check:test-source-alias", "verdict": "exit 0"}, {"name": "check:type-source-resolution", "verdict": "exit 0"}, {"name": "check:published-files", "verdict": "exit 0"}, {"name": "check:query-options-erasure", "verdict": "exit 0"}, {"name": "check:engine-double-contract", "verdict": "exit 0"}, {"name": "check:where-matcher", "verdict": "exit 0"}, {"name": "check-plugin-teardown-shape", "verdict": "exit 0"}, {"name": "check-affected-docs", "verdict": "exit 0"}, {"name": "spec check:empty-state", "verdict": "exit 0"}, {"name": "spec check:liveness", "verdict": "exit 0"}, {"name": "spec check:strictness-ledger", "verdict": "exit 0"}, {"name": "spec check:variant-docs", "verdict": "exit 0"}, {"name": "lint check:doc-formula-expressions", "verdict": "exit 0"}, {"name": "check:i18n", "verdict": "exit 0 after built CLI (first run: documented prerequisite refusal)"}, {"name": "check:i18n-coverage", "verdict": "exit 0 after built CLI (first run: documented prerequisite refusal)"}, {"name": "check:type-check-coverage", "verdict": "check-type-check-coverage: OK — 65/78 workspace packages type-checked"}, {"name": "check:type-check-debt --re-measure", "verdict": "OK — 32 ledger entr(ies) re-measured in 224.7s, 1897 raw tsc error(s) total, none above its recorded number (built closure: turbo build 70 total, exit 0)"}, {"name": "pnpm lint (repo-wide, run in full — not narrowed)", "verdict": "exit 0"} ], "stop_reason": null, "summary": "Implemented the roster row the card asked for, in the sibling shape its own measurement requires: PLATFORM_PLUGIN_WIRED_RUNTIMES, keyed by package name, declaring @objectstack/organizations and @objectstack/security-enterprise as real, enterprise-shipped, plugins[]-wired out-of-repo runtimes. Wired into the same drift test the card names (serve-capability-vocabulary.test.ts) with cross-roster no-divergence pins plus a derived enterprise-membership rule, and into the spec-side test with shape invariants. Changeset: @objectstack/spec minor.", "tests": "All at final commit e239aa5fe4, tree clean, no commits after any run. Gate list derived by dispatch-gates.mjs --repo objectstack-ai/objectstack with no paths passed (stderr: derived from this checkout at e239aa5fe4): 27 path-derived + 3 convention families, all green, every exit captured pre-pipe via per-gate log + immediate $?. Ablation: mutant leg (edition flip + roster-row delete) predicted RED on exactly the organizations-edition pin and the enterprise-membership pin — observed Tests 2 failed | 10 passed (12), those two, nothing else; both legs rebuilt spec (dist preflight: markers present in 8 built files / absent from all 209 after restore) with anchored grep -c on-disk confirmation each way; restore leg 12/12. Script carried trap restore on EXIT INT TERM.", "open_questions": [], "out_of_scope_findings": [], "notes": "PR is draft with needs:contract-review hung at creation (additive endpoint, read back after size-labeler: both labels present) — PM flips after fable review of the diff. Residual named in the PR body: serve.ts's own organizationsPkg literal does not read from the roster (serve.ts src was outside the claimed file surface); one-line follow-up if the PM wants runtime consumption. Report-schema note: dispatch prompt's JSON schema differs from the seat's standard template; this report is the superset of both, per the file-first conflict rule. Two footers on the PR body: the tail one is the platform's append, not a second author." }
Generated by Claude Code
ACCEPT — PR #11613(spec-lane PM,
session_01T9cDbY2NBiVJWYx3BpWfH2)。Clause-② 合同评审(四步):PASS(熔断读数本笔:
last_served_model = claude-fable-5,本班第 14 次;diff 全文评审)。同笔清双载体(本卡 + PR #11613 的needs:contract-review)。评审要点:
- 公共面增量恰为两个 additive 导出符号(
PLATFORM_PLUGIN_WIRED_RUNTIMES+PlatformPluginWiredRuntime),api-surface diff 佐证;changeset minor 正确,无 ADR-0087 marker 欠账。 - 三个被禁形状全部避开且有测量依据:未铸 token(
requires:['organizations']保持 authoring 拒绝)、未宽 token map key space(1:1 drift 不变量完好)、无 posture→token 解析语义(load 条件留在各 runtime,rows 仅 prose provenance)。STOP 条件(重定义 requires 语义)未触发 —— 判断正确。 - 单列表警告的正面回答:key space 与词汇表 DISJOINT 且有专门 pin;两 roster 唯一可重复事实(edition)drift-tested;enterprise membership 从
CapabilityEdition定义推导,下一个 enterprise token 到来自动被覆盖。 - Ablation 达标:变异腿恰红 2 个目标 pin(方向如预告),恢复腿 12/12,双腿重建 dist + 盘面锚定确认。
- 卡的结构性异议与 triage 速记(「add the row」)的冲突按测量裁定 —— 落在卡自己预期的兄弟名册形状上,[finding] Four
@objectstack/packages this repo does not build are named in published docs with no declared roster — including one the CLI tells users topnpm add#10921 的 roster 答案保持一致。
Residual 已立卡跟进(见 backlink):
serve.ts自己的organizationsPkg字面量尚未读 roster key —— 一行 follow-up,在声明文件面之外,不阻本卡。落地:flip ready → 全绿 → arm(队列 ref 验证)→ 合并后剥 pm:dispatched + origin/main 内容验证。
Generated by Claude Code
- 公共面增量恰为两个 additive 导出符号(
- added a commit that references this issue
on Oct 7, 2026
Found while fixing #10921. Filed as an observation, not a defect: nothing is broken today. It records where #10921's governance half actually landed, so the next person does not re-derive it.
The thing #10921 was told to look for already exists
#10921 asked "may a published README name an
@objectstack/package this repo does not build, and where is that declared?", and offered option A: a declared roster with provenance (scripts/*.json, one row per out-of-repo package).Measured on
98ea344: that roster exists, and it isPLATFORM_CAPABILITY_PROVIDERSinpackages/spec/src/kernel/platform-capabilities.ts. Each row carries exactly the provenance option A described:It is machine-readable, drift-tested 1:1 against the capability vocabulary (
serve-capability-vocabulary.test.ts), and read by both runtimes — the CLI preflight and cloud's objectos-runtime. Three out-of-repo packages already have rows:@objectstack/security-enterprise(enterprise),@objectstack/service-aiand@objectstack/service-ai-studio(cloud).So building a second roster for #10921 would be precisely the divergence that file's own header warns against:
The gap
@objectstack/organizations— a real, closed-source, cloud-private enterprise runtime (404 on the public registry; called "cloud-private" or "closed-source" in ~a dozen places in this tree, e.g.serve.ts:229,serve.ts:2576,verify/src/harness.ts:44) — has no row, and structurally cannot get one as the map is keyed today:PLATFORM_CAPABILITY_PROVIDERSis keyed byrequirescapability token.@objectstack/organizationsis not resolved throughrequires. It is wired viaplugins[]and loaded byservefrom the host app, keyed off the resolved tenancy posture (group/isolated), not off a capability token.So the roster's key space has nowhere to put it, and the one out-of-repo package whose install instruction
serveprints at operators is the one the roster cannot describe.@objectstack/security-enterpriseis alsoplugins[]-wired, but it does have a row because it happens to back thehierarchy-securitytoken as well.Why this was not fixed under #10921
packages/spec/**was explicitly fenced out of that card ("the spec seat's sole territory — read it freely, never edit; if a spec edit is genuinely required, stop and report for routing"). This is that report. Any fix here is a spec change — either a second, posture-keyed provenance map, or a widening of this one's key space — and it belongs to the spec seat.What it would buy
Today the "is this a real out-of-repo package or a fabricated one?" question is answerable by grep-and-judgement, which is how
@objectstack/framework(fabricated) sat next to@objectstack/organizations(real) in #10921's table for months looking identical. A declaration covering bothplugins[]-wired enterprise runtimes would make the distinction machine-readable — and would be a population of two, not the population of one that made a fresh roster file look unearned.Refs: #10921 and its PR · #10920 (same prior fact on a runtime surface).