Skip to content

package-registry is on the always-on slate but Serve.CAPABILITY_PROVIDERS does not key it — the always-on mount is silently inert (#17676 ruling A' runtime half) #19387

Closed

Description

@huangyiirene

What is wrong

'package-registry' is an always-on platform capability that mounts nothing, and it fails silently. Ruling A′ on #17676 (decision batch #125, maintainer 「同意」 2026-09-13) landed its spec half; the runtime half — the entry that actually mounts the provider — is not landed, so the ruling's own consequence is false on today's tree.

The chain, measured on origin/main 8271c814253fdd2629d3b608b73de14efb67f168

link reading
the token is always-on packages/spec/src/kernel/platform-capabilities.ts:312+ — PLATFORM_ALWAYS_ON_CAPABILITIES lists 'package-registry'
the spec already names its provider same file :179 — 'package-registry': { package: '@objectstack/service-package', edition: 'open' }
serve force-appends every slate token packages/cli/src/commands/serve.ts:2800-2802, the ALWAYS_CAPS loop
⛔ but the CLI mount table does not key it Serve.CAPABILITY_PROVIDERS (serve.ts:1863+) keys automation · analytics · audit · cache · storage · queue · job · messaging · triggers · realtime · mcp · **marketplace** · email · sms · sharing · pinyin-search · reports · approvals · settings · webhooks — ⛔ no package-registry
⛔ and the miss is silent the no-provider branch warns only when declaredRequires.has(cap) && !PLATFORM_CAPABILITY_TOKENS.includes(cap). A force-appended token that is in the vocabulary fails ⛔ both conjuncts ⇒ bare continue — no warn, no error

⇒ on a stock boot of an app that does not itself declare requires: ['marketplace'] (examples/app-crm declares ['ui','automation']), POST /api/v1/packages reaches protocol.installPackage with no package service and registers the package in memory only. It does not survive a restart. That is #17676's defect, still live.

⭐ Worse than a missing mount: a reader of the spec sees package-registry on the always-on slate and reasonably concludes it is mounted everywhere. AGENTS.md principle 3 — Absence must be loud is exactly what this violates.

The shape question — and how much of it is already decided

Two shapes are available. ⚠️ They are not equal candidates, and the reason is textual rather than a preference:

what it does cost
A — ADD key package-registry at @objectstack/service-package too, leaving marketplace pointing there as well Smallest diff, and hasPluginMatching already stops a double mount. ⛔ But it re-enacts the conflation the carve-out exists to end, and it contradicts ruling A′ item 1's own sentence.
B — MOVE package-registry takes @objectstack/service-package; marketplace is repointed at the browse surface (MarketplaceProxyPlugin / MarketplaceInstallLocalPlugin in @objectstack/cloud-connection, off a resolved marketplace URL, ADR-0008) ⚠️ Changes what requires: ['marketplace'] means for apps shipping today. Needs a migration story, and probably an ADR-0087 disposition.

Ruling A′ item 1 already says what the two names mean, and it is quoted in the spec file itself: the persistence half "is a core capability named for what it is and mounted always … marketplace is left naming only the optional catalogue / browsing half." ⇒ A contradicts the landed ruling; only B makes item 2's sentence ("therefore always find the package service on a stock boot") true while leaving the two names meaning what the ruling says.

⚠️ What ruling A′ did not decide, and this card must: the migration for declarers. The spec's provider row is explicit that it declines to pre-empt this —

"the two rows agreeing on a package is what the carve-out INHERITED, not what it decided: repointing marketplace at the browse surface moves the runtime's own resolver with it and is #17676's engine-lane half, which this row deliberately does not pre-empt."

A real declarer to design against, ⛔ not a hypothetical: examples/app-showcase/objectstack.config.ts:107 declares 'marketplace', and its own comment at :103 says it declares it for "PackageServicePlugin (sys_packages store)" — i.e. for the persistence half. The same file separately wires the browse plugins through plugins[]. ⇒ under B that declaration becomes vestigial (the store arrives always-on) and the browse auto-mount is skipped by the identity guard — but an out-of-repo consumer that declared marketplace for the store has no such explicit wiring, and the taker must say what happens to it.

⭐ The pin that is waiting to be written

packages/cli/test/serve-capability-vocabulary.test.ts deliberately declines to pin that Serve.CAPABILITY_PROVIDERS lacks package-registry, so the engine lane's own change would not be turned red for doing the ruled thing. ⇒ today nothing mechanical would notice if this half were forgotten again — the gap lives only in two prose comments, in that test and in the spec.

Whoever takes this should convert that prose into the pin it was waiting to be able to write. ⛔ Otherwise the next carve-out repeats this exact failure.

Acceptance

  1. A stock boot (an app declaring neither marketplace nor package-registry) mounts the package service, and an API-created package survives a restart — which is A writable package created via POST /api/v1/packages is registered in memory only — it does not survive a restart, and leaves its published metadata orphaned #17676 ruling A′ item 5, whose three-probe acceptance ⛔ cannot be met by anything until this lands.
  2. The absence direction is pinned, so a future slate entry with no mount entry goes red.
  3. The declarer migration is stated in writing, with its ADR-0087 disposition answered rather than assumed.

File surface

packages/cli/src/commands/serve.ts (the mount table) and packages/cli/test/serve-capability-vocabulary.test.ts (the pin). ⚠️ Touching examples/app-showcase/objectstack.config.ts depends on the migration answer, ⛔ not assumed here.

Lane — ⛔ deliberately unlabelled

Left for triage. ⚠️ The two prose notes call this "the engine lane", meaning #17676's lane — but the files live in packages/cli, which the lane table routes elsewhere. ⇒ the routing is genuinely a triage call and ⛔ this filer is not making it and has written no domain:* label.

⚠️ If the taking lane's PM reads the declarer-meaning change as a contract-shape proposal rather than execution, the four-axis decision route is the right escalation — ⛔ this filer is not foreclosing it, and is equally ⛔ not manufacturing a decision the maintainer already made in item 1.

Dedupe words (⛔ the filer does not dedupe)

package-registry inert · CAPABILITY_PROVIDERS · ALWAYS_ON silent continue · marketplace carve-out · #17676 runtime half

Provenance

Surfaced as the fork in the os-dev report on #17676 (PR #19385) and independently re-derived link-by-link by the domain:engine execution PM seat, round 7 — which also records there that the dispatch order's assumption that item 1 discharged item 2 was the seat's own error. Related: #17676 (the ruling) · #18053 (item 1's carrier) · PR #19385 (items 2/3).


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Sep 22, 2026

    @objectstack-fleet
    Contributor

    Triage: domain:cli (packages/cli/src/commands/serve.ts) · p2 · Bug · area:devpath; rationale: a published always-on capability token that the boot never keys — declared contract, measured absent

    Path: 发布并装进一个环境 —— 装进来 | platform-core.manifest-install-contract | P4 | p2
    Graded by the triage seat (session_01Tw7jnJinGHvoGSi8aFkhPJ) at 2026-09-22T17:28Z. ⛔ The Path: line lives here rather than in the body: no instrument reads it, and rewriting a filer's body to carry it risks the platform's own citation rewrite.

    Class (b), verified by this seat on origin/main, ⛔ not taken from the card. packages/spec/src/kernel/platform-capabilities.ts:58 lists package-registry inside PLATFORM_ALWAYS_ON_CAPABILITIES, and git grep -c package-registry -- packages/cli/src/commands/serve.ts answers 0 while CAPABILITY_PROVIDERS is live in that same file (its own prose at :1573 and :1636 discusses the roster). ⇒ a token the platform force-appends mounts nothing, and the miss is silent.

    ⚠️ One leg is the card's, ⛔ not this seat's: the restart-loses-the-package path was not re-driven here. The dispatch reproduces it first.

    Lane — packages/cli is domain:cli by the 域车道 table. ⚠️ The card's prose calls this 「the engine lane」; the table routes by the file the fix lands in, ⛔ not by the prose.

    Level — p2, level with what it blocks: #17676 is open and carries Blocked-by: #19387.

    The one question the card leaves open is already answered, so nothing here goes to the maintainer: migration for out-of-repo requires: ['marketplace'] declarers is settled by NORTH-STAR 〈阶段姿态〉 —— 「退役立即生效,无过渡窗口、无别名双拼」.

    Dedupe — repo-scoped semantic query on the serve-capability mechanism: 8 hits including closed, 1 open (this card). No twin.

    Generated by Claude Code

  2. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    Contributor

    Claim: PM loop round 1
    Session: session_01TnPAC1UsTGfHPXVUCL6iLn
    Branch: claude/issue-19387-package-registry-mount
    Worktree: objectstack-issue-19387
    Domain: domain:cli
    Seat: domain:cli#1
    File surface: packages/cli/src/commands/serve.ts (the CAPABILITY_PROVIDERS mount table and the no-provider branch), packages/cli/test/serve-capability-vocabulary.test.ts and sibling pins under packages/cli/test/, and one .changeset/19387-*.md. packages/spec/** and examples/app-showcase/objectstack.config.ts are read-only (stop on breach; explain in the report)
    File surface amendment (2026-09-24T14:29Z, same round, patch round): + packages/metadata-protocol/src/protocol.ts, the installPackage docblock paragraph only (prose, no behaviour). It is a cross-lane (domain:engine) face, declared on #17676 as 5816111791, and it is fixed here because PR #19983 makes that published sentence false. No open PR touches that file (39 enumerated).
    Container & model: M, mode:subagent, model: default judgment tier (this act's node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --tier over the two paths answered: no path-derived mandate). A ruling implementation that touches a boot-composition surface gets the default judgment tier.
    Clause-②: no
    Thread-read: 5780990479
    Serial constraints cleared: lane in flight 0 at claim. File lists of all 32 open PRs read this act: none touches serve.ts or the vocabulary pin. #19845 (engine), which read serve.ts, is closed. #17676 (domain:engine, pm:blocked) waits on this card via Blocked-by: #19387 and is not in flight.

    Taken 2026-09-24T13:00Z, origin/main 2c1011b01b. The dev posts no second claim; this comment is its identity.

  3. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    Contributor

    os-dev-report

    {
      "issue": 19387,
      "status": "done",
      "branch": "claude/issue-19387-package-registry-mount",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/19983",
      "session": "session_01TnPAC1UsTGfHPXVUCL6iLn — the parent PM session (mode:subagent shares it); this run's identity is the branch named in claim 5814614529",
      "premise_still_valid": true,
      "summary": "Serve.CAPABILITY_PROVIDERS now keys 'package-registry' at @objectstack/service-package / PackageServicePlugin, the provider the spec's PLATFORM_CAPABILITY_PROVIDERS row declares, so a stock boot (an app declaring neither token) mounts the package service. Measured with serve --dev on one SQLite file: on origin/main 2c1011b0, POST /api/v1/packages answered 201 and printed the in-memory-only warning, and after a restart GET /api/v1/packages/com.example.survivor answered 404. On this branch it answers 200 and the boot rehydrates the package from sys_packages. PM mechanism assumption 4 was FALSIFIED by measurement. hasPluginMatching reads only the app's own plugins[], so the table entry alone made a requires:['marketplace'] declarer mount PackageServicePlugin twice (WARN Plugin superseded: 'package-service', ×2 in the banner row). The resolver now also consults resolverMounted, the instances it has itself mounted, and declarers are measured unaffected (×1, no supersede). The prose in serve-capability-vocabulary.test.ts that declined to pin the absence is now the pin: every always-on token keys a CAPABILITY_PROVIDERS entry or a CAPABILITY_TO_TIER tier. By measured call, no runtime warning was added to the no-provider branch: the pin makes that case unreachable in a published CLI, because spec and cli share a fixed release group. The marketplace repoint (the card's shape B) is not in this diff. It is reported below as a class-(b) Seam finding for the spec seat.",
      "tests": "All at 6496714f. (1) pnpm --filter @objectstack/cli exec vitest run --project unit --maxWorkers=2: 222 files. On first run 220 passed and 2 were refused 'packages/cli is not built' (published-subpath-console.pin, published-subpath-hook-body.pin; a build prerequisite, not a verdict). After pnpm --filter @objectstack/cli build: 2 passed, 29 tests. Totals 3116 passed, 29 skipped. (2) Targeted unit (vocabulary, identity, serve-defaults, capability-preflight): 4 files, 122 passed. (3) OS_TEST_TIERS=nightly … vitest run --project integration test/serve-package-registry-always-on.e2e.test.ts: 5 passed. (4) Neighbouring nightly serve e2e files that boot serve (17 files): 75 passed. (5) pnpm --filter @objectstack/cli run typecheck: exit 0, and tsc -p tsconfig.test.json --listFilesOnly contains all 3 touched test files. REVERSE CHECKS, each through scripts/ablation-replace.mjs (anchor count 1→0 and blob change confirmed, then restored with blob == HEAD and git diff HEAD empty): (a) delete the 'package-registry' table entry, then run the vocabulary and identity pins: 2 red. The new pin says 'expected [ 'package-registry' ] to deeply equal []', and the identity coverage assertion goes red too. Direction as predicted. (b) Same deletion, then run the e2e: 3 red (banner row, in-memory-only line, post-restart 404); the declarer block stays green. (c) Delete 'resolverMounted.push(provider);', then run the e2e: 1 red (declarer boot prints Plugin superseded: 'package-service'); the stock block stays green. No dist leg: the unit pins import ../src/commands/serve.js and the e2e spawns bin/run-dev.js through tsx, so both read src/. MANUAL repro, before and after, on scratchpad fixtures: base.db restart read 404 → fixed.db 200. Declarer boots: origin/main ×1 no supersede; table-only ×2 plus supersede WARN; this branch ×1 no supersede. memory:// stock boot: +4 WARN lines (3 'Raw execution not supported in InMemory driver' for the sys_packages DDL and query, plus 'Package hydration from sys_packages SKIPPED'). Authenticated requests on memory:// answer 503 from the sys_position authorization read, which predates and is unrelated to this diff.",
      "mcp_calls": "0",
      "api_writes": "2 — (1) pr_create through scripts/pm/with-fleet.sh --via dispatch (repository_dispatch fw-20260924T142024Z-b38b41, run 36012080362, which executed POST /repos/objectstack-ai/objectstack/pulls with draft forced) → PR #19983; (2) this os-dev-report via node scripts/pm/post-stamped.mjs --comment=19387 (POST /repos/objectstack-ai/objectstack/issues/19387/comments). Zero label writes, as ordered. git push ×3 (the empty-branch probe and two commits) is not a REST write. One read-side git fetch (--depth=1 of commit 621a4876) was added to the shared object store; see deviations.",
      "gates": {
        "node scripts/check-adr-0087-registration.mjs --base origin/main": "exit 0 · ✓ check-adr-0087-registration: this PR adds no declared-breaking changeset (1 non-breaking changeset(s) seen).",
        "node scripts/check-adr-0087-registration.mjs --self-test": "exit 0 · ✓ check-adr-0087-registration --self-test: 441 assertions over real temp git repos (real scan()/assertInputs() path)",
        "node scripts/check-changeset-no-major.mjs --base origin/main": "exit 0 · ✓ This diff introduces no `major` bump.",
        "node scripts/check-changeset-no-major.mjs --self-test": "exit 0 · ✓ check-changeset-no-major --self-test: 339 assertions (frontmatter dialects measured against @changesets/parse + the pre/exit exemption switch in both directions + the #7005 diff scoping over real temp git repos + the #",
        "node scripts/check-ci-filter-parity.mjs": "exit 0 · OK: all 185 declared cross-package glob(s) (132 unique) are covered by `core` or `crosspkg`, every `crosspkg` entry still covers one, and the `test` job's `if:` still names both filters.",
        "node scripts/check-closing-keyword-parity.mjs": "exit 0 · check-closing-keyword-parity: OK (3 parsers agree on all 9 keywords and both measured separators; sweep found 5 file(s) carrying the grammar across 9385 tracked file(s), all registered).",
        "node scripts/check-closing-keyword-parity.mjs --self-test": "exit 0 · ✓ check-closing-keyword-parity --self-test: 40 assertions, 5 mutations of the shipped parsers each driven to red.",
        "node scripts/check-comment-mask-adoption.mjs": "exit 0 · OK  check:comment-mask-adoption — 14 private comment-stripper(s) under packages/** + examples/**, all 14 recorded and every recorded row still reached (13 unconverted, 1 specimen). A new one reds here.",
        "node scripts/check-comment-mask-adoption.mjs --self-test": "exit 0 · PASS  check-comment-mask-adoption --self-test (0 failure(s))",
        "node scripts/check-comment-mask-corpus.mjs": "exit 0 · ✓ comment-mask corpus sweep [scripts/js-comment-mask.mjs]: 7070 files, 0 disagree, 0 unparseable, 85.9s (comparator self-test: 26 cases pass).",
        "node scripts/check-empty-changeset.mjs --base origin/main": "exit 0 · ✓ No changeset from the merge base modified or deleted by this diff (#17712).",
        "node scripts/check-empty-changeset.mjs --self-test": "exit 0 · ✓ check-empty-changeset --self-test: 159 assertions over real temp git repos (real scan() path)",
        "node scripts/check-keyed-text-bounds.mjs": "exit 0 · ✓ check:keyed-text-bounds: 112 *.object.ts files under packages/** + apps/** + examples/** (walk is repo-wide; 0 outside), 117 object declarations, 250 declared index entries, 592 text-family fields; 147 keyed text-famil",
        "node scripts/check-keyed-text-bounds.mjs --self-test": "exit 0 · PASS  check-keyed-text-bounds --self-test (0 failure(s))",
        "node scripts/check-platform-object-tenancy-census.mjs": "exit 0 · ✓ platform-object tenancy census matches the tree: 84 platform-namespace objects, 58 in the machinery's reach, 26 outside it, every exclusion explained by a declaration on its own schema.",
        "node scripts/check-platform-object-tenancy-census.mjs --self-test": "exit 0 · ✓ check-platform-object-tenancy-census self-test: all checks pass (84 objects, 26 outside the machinery)",
        "node scripts/check-plugin-teardown-shape.mjs": "exit 0 · ✓ check:plugin-teardown-shape: 69 Plugin implementation(s) across 6501 source(s) under packages/**; every teardown-shaped method (stop / shutdown / close / dispose) sits beside a real destroy() (0 known-unreached, ⛔ SHRI",
        "node scripts/check-plugin-teardown-shape.mjs --self-test": "exit 0 · ✓ check-plugin-teardown-shape self-test: 48 cases pass (real pre-#10375 fixture reds, the repaired file and both delegating-alias directions stay green, every roster name reds, every excluded name stays green, and all fi · [first run exit 3 PREREQUISITE NOT MET (shallow clone lacked pinned fixture commit 621a4876); rerun after git fetch --depth=1 of that commit]",
        "node scripts/check-registry-log-declared.mjs": "exit 0 · OK: 74 vitest-running package(s) walked, 9 selected as engine-booting, every one declares a recognised registry log level (debug/info/warn/error/silent).",
        "node scripts/check-registry-log-declared.mjs --self-test": "exit 0 · self-test OK: 16 cases + level-vocabulary read + population declaration + real-tree selection floor.",
        "node scripts/check-rest-log-spy-declared.mjs": "exit 0 · OK: 29 of 196 test file(s) beside packages/rest/src/log.ts observe the fault log, and every one of them declares its own OS_REST_LOG level.",
        "node scripts/check-rest-log-spy-declared.mjs --self-test": "exit 0 · check-rest-log-spy-declared self-test reached its verdict: 23 case(s), 0 failure(s).",
        "node scripts/check-system-context-census.mjs": "exit 0 · check-system-context-census: OK — 110 elevation read sites in 20 packages across 45 files, living in 91 symbol(s); the page cites 104 symbol(s) against 104 required, over 128 anchors and 8 file-level citation(s); 21 decl",
        "node scripts/check-system-context-census.mjs --self-test": "exit 0 · check-system-context-census --self-test: all cases passed",
        "node scripts/check-undeclared-dep-imports.mjs": "exit 0 · ✓ check:undeclared-dep-imports: 81 workspace packages under packages/** + apps/** + examples/**, 2578 non-test src files, 2068 @objectstack/* specifiers (0 assembled, not judged); 1 ledger row(s), all evidence intact.",
        "node scripts/check-undeclared-dep-imports.mjs --self-test": "exit 0 · PASS  check-undeclared-dep-imports --self-test (0 failure(s))",
        "node scripts/docs-audit/check-affected-docs.mjs": "exit 0 · ✓ affected-docs self-test: 605 cases pass.",
        "node scripts/docs-audit/check-drift-comment.mjs": "exit 0 · ✓ check-drift-comment: 66 cases pass across 5 fixture diff(s).",
        "node scripts/pm/release-rehearsal-clone.mjs --self-test": "exit 0 · ✓ self-test passed",
        "pnpm --filter @objectstack/spec run check:duration-unit-keys": "exit 0 · ✓ check:duration-unit-keys — 204 unit-declaring numeric key(s) across 2575 source file(s) all carry their unit in the key name (or in a sibling `unit`, or under a declared exemption: 6 declared duration type(s) (`Duratio",
        "pnpm check:changeset-gate-self-tests": "exit 0 · ✓ check-changeset-no-major --self-test: 339 assertions (frontmatter dialects measured against @changesets/parse + the pre/exit exemption switch in both directions + the #7005 diff scoping over real temp git repos + the #",
        "pnpm check:cli-test-child-env": "exit 0 · ✓ check:cli-test-child-env: 90 spawner source(s) among 195 under packages/cli/test/**; no new bulk process.env copy reaches a spawned child, all 108 spawn call(s) declare their child's env, and all 6 spawn(s) of the buil",
        "pnpm check:cross-package-test-inputs": "exit 0 · OK: 29 package(s) read outside themselves, all declared, and turbo.json hashes every declared glob (6 of them on a split \"test:repo\" task); 13 walked root(s) judged, 3 on ACCEPTED_WALK_RADII; 2092 test file(s) import a w",
        "pnpm check:dispatcher-error-vocabulary": "exit 0 · check-dispatcher-error-vocabulary: OK — 52 unregistered code-stamping site(s), all classified; 2 awaiting a ledger entry (#8846).",
        "pnpm check:doc-authoring": "exit 0 · ✓ doc authoring guard: sibling-package prose ids hold the baseline — 817 pinned site(s) across 231 file(s), 90839 string(s) read in 1250 parsed source(s), no growth, no burn-down unrecorded.",
        "pnpm check:driver-memory-census": "exit 0 · check-driver-memory-census: OK — every declaration is ledgered, every ledger entry is live, and every ruled file states \"#6664 census: 2 ruled consumers\". This gate polices the census, never investment.",
        "pnpm check:dts-closure": "exit 0 · check-dts-closure: 73 built package(s) swept - 165/165 declared declaration file(s) present across 73 package(s); 0 built package(s) declare no declaration entry point and owe none. · [first run exit 0 over 57 built packages; rerun after full build over 73]",
        "pnpm check:dual-build-cjs-loads": "exit 0 · ✓ check:dual-build-cjs-loads — 104 published require entry point(s) across 67 package(s) load; 620 emitted CommonJS file(s) parse; 1 cross-format behaviour probe(s) agree; 102 require condition(s) resolve a CommonJS-flav · [first run exit 3 PREREQUISITE NOT MET (12 packages unbuilt); rerun after turbo build --filter=!@objectstack/docs]",
        "pnpm check:engine-double-contract": "exit 0 · check-engine-double-contract: OK — 897 pinned, 133 in the DEBT ledger, 3 exempt.",
        "pnpm check:gitlink-declared": "exit 0 · check-gitlink-declared: OK (9385 index entries -- 0 gitlink(s) at mode 160000; no .gitmodules in the index, so nothing is declared; nothing to declare).",
        "pnpm check:i18n": "exit 0 · check-i18n-bundles: OK (9 package(s) — all bundles in sync, no undeclared authoring keys).",
        "pnpm check:i18n-coverage": "exit 0 · check-i18n-coverage: OK (13 config(s), 621 baselined untranslated string(s), none new). · [first run exit 3 COULD NOT MEASURE (connector-mcp unbuilt); rerun after turbo build --filter=!@objectstack/docs]",
        "pnpm check:i18n-walk-parity": "exit 0 · ✓ check-i18n-walk-parity: 10 declared group(s), 8 walked, 2 exempted — every declared group has an extractor face.",
        "pnpm check:issue-citations": "exit 0 · ✅ check-issue-citations --self-test: grammar narrowed, four 404 causes kept apart, both board strategies agree, diff scope red AND green, scope contract pinned (73 cases, 7 batteries)",
        "pnpm check:lean-entry-closure": "exit 0 · ✓ check-lean-entry-closure: 2 published condition(s) measured from a real load.",
        "pnpm check:logger-receiver-detach": "exit 0 · OK  every log channel keeps its receiver: 2847 non-test TS file(s) walked, 0 detach(es) on the 5 declared receiver-sensitive sink spelling(s).",
        "pnpm check:nul-bytes": "exit 0 · check-nul-bytes: OK (scanned 9378 text file(s) -- 9378 tracked, 0 untracked-not-ignored; skipped 7 binary; no raw ASCII control bytes).",
        "pnpm check:objectql-double-limit": "exit 0 · OK  ObjectQL double `limit` conformance holds: 400 double(s) graded, 202 apply the caller's bound or refuse it loudly.",
        "pnpm check:objectui-changeset": "exit 0 · ✓ objectui-range --self-test: all checks passed",
        "pnpm check:org-identifier": "exit 0 · check-org-identifier: OK (2869 author-facing source file(s), 17 session binding(s) resolved, no removed session.tenantId alias).",
        "pnpm check:page-declaration-shape": "exit 0 · check-page-declaration-shape: OK — 34 page entries across 2859 sources under packages/**, examples/**, apps/** all reach the kernel through a discoverable declaration (`: Page` or `definePage()`).",
        "pnpm check:pm-changeset-deadline-census": "exit 0 · ✓ changeset-deadline-census --self-test: all cases passed across 5 batteries (what counts as a named target, the controls that make a zero a reading, the verdict truth table including the inconclusive refusal, the bucket",
        "pnpm check:published-files": "exit 0 · ✓ check:published-files — 70 publishable package(s) of 81 workspace member(s) declare a `files` whitelist that covers every entry point plus CHANGELOG.md and admits no test, test-harness config or build script; 1 publish",
        "pnpm check:query-options-erasure": "exit 0 · ✓ query-options-erasure ratchet holds: 67 unswept non-test site(s) in 17 file(s), none new, and every file measured parsed. Every other non-test file under packages/ is covered by `pnpm lint`.",
        "pnpm check:refd-timer-probe": "exit 0 · OK  check-refd-timer-probe: 7065 source file(s) swept; the process-global timer probe is read in packages/qa/refd-timer-testkit/src/index.ts and nowhere else.",
        "pnpm check:route-envelope": "exit 0 · ✓ Express-style response modules — 4 module(s) discovered and audited (walked, not enumerated — #9937), 12 hand-built body/bodies (count reported, NOT pinned): 2 conformant, 2 ratcheted, 0 exempt, 0 vendor-wire",
        "pnpm check:slot-lookup": "exit 0 · ✓ slot-lookup ratchet holds: 106 unswept site(s) in 25 file(s), none new, and every file in the population parsed. Every other file under packages/ is covered by `pnpm lint`.",
        "pnpm check:sourcemap-no-sources-content": "exit 0 · check-sourcemap-no-sources-content: 69 built package(s) swept - 506 map(s), none embed source text.",
        "pnpm check:test-source-alias": "exit 0 · check-test-source-alias OK — 74 packages with tests scanned; 61 registered as still resolving a workspace dep through `dist/`; 49 published subpath(s) resolved through every alias table.",
        "pnpm check:tier-file-adoption": "exit 0 · OK: 81 workspace package(s) walked, 70 nightly-tier test file(s) on disk (70 e2e, 0 live), owned by 1 package(s); every one reads OS_TEST_TIERS.",
        "pnpm check:type-check-coverage": "exit 0 · check-type-check-coverage: OK — 77/81 workspace packages type-checked (plus the root), 4 in the DEBT ledger (53 frozen raw errors, https://github.com/objectstack-ai/objectstack/issues/4311), 1 exempt.",
        "pnpm check:type-check-debt": "exit 0 · check-type-check-coverage --re-measure: OK — 4 ledger entr(ies) re-measured in 28.4s, 53 raw tsc error(s) total, none above its recorded number.",
        "pnpm check:watch-hint-literal": "exit 0 · ✓ check-watch-hint-literal: 71 declaration(s) across 4 rostered name(s) -- ROOT_DIR_WATCH_HINTS 47, ROOT_FILE_WATCH_HINTS 13, ROOT_WATCH_HINTS 3, DECLARED_WATCH_HINTS 8 -- every one an array of quoted literals inside its",
        "pnpm check:where-matcher": "exit 0 · ✓ where-matcher conformance holds: 422 matcher(s) discovered, 422 answer the combinator battery correctly or refuse it loudly (279 refuse).",
        "pnpm lint (lane addition, full union: eslint . --no-inline-config)": "exit 0 · no findings printed; os-verify-lock VERDICT command-exit 0 at 6496714f",
        "pnpm --filter @objectstack/cli run typecheck": "exit 0 · check:test-typecheck: OK — @objectstack/cli test layer compiles under packages/cli/tsconfig.test.json; 3 file(s) / 28 error(s) / 6 pinned signature(s) held in test-typecheck-debt.json",
        "node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --ran ran-exit.txt": "exit 0 · ✓ dispatch-gates --ran: 64 derived famil(ies) accounted for — 64 run, 0 NOT-MEASURED (a DERIVED zero — all 64 recorded an exit code and none of them is 3)."
      },
      "line_budget": "n/a",
      "ci": "Not awaited, per the dispatch contract. At report time the PR head 6496714f had 16 check runs: 14 in_progress, 1 success, 1 skipped.",
      "files_changed": [
        "packages/cli/src/commands/serve.ts (+41/-3: package-registry row in CAPABILITY_PROVIDERS; resolverMounted in the capability resolver; no-provider-branch comment)",
        "packages/cli/test/serve-capability-vocabulary.test.ts (absence pin replaces the prose that declined it)",
        "packages/cli/test/serve-capability-identity.test.ts (EXPECTED_PROVIDER_NAME row)",
        "packages/cli/test/serve-package-registry-always-on.e2e.test.ts (new; nightly tier by name, integration project by behaviour)",
        ".changeset/19387-package-registry-mount.md (@objectstack/cli patch, Clause-②: no)"
      ],
      "deviations": [
        "PM mechanism assumption 4 falsified (measured): hasPluginMatching does not stop the double mount, because it reads only config plugins[]. The in-scope repair (resolverMounted in serve.ts, inside the claimed file surface) goes beyond the suggested route's single table entry.",
        "Runtime no-provider branch: no warning added, by measured call. The absence pin plus the fixed release group make an unmounted always-on token unreachable in a published CLI, so a warning would be unreachable code. The reasoning is recorded as a comment at the branch and in the PR body.",
        "The new e2e is named *.e2e.test.ts, the repo convention for every file that boots serve (all 17 existing ones are). It therefore runs nightly, not per-PR. The per-PR guard is the unit absence pin plus the existing package drift pin. It was run locally under OS_TEST_TIERS=nightly.",
        "Gate prerequisites supplied locally: git fetch --no-tags --depth=1 origin 621a487607881c66b2899b7e3477115229a156b4, into the shared .git, for check-plugin-teardown-shape --self-test's pinned fixture (a shallow clone lacks it); turbo run build --filter=!@objectstack/docs for check:dual-build-cjs-loads and check:i18n-coverage (both exit 3 before, exit 0 after). The --ran record carries the post-prerequisite exit codes; the first exit-3 readings are noted in the gates map.",
        "Beyond what was owed: ran the 17 neighbouring nightly serve-booting e2e files locally (75/75), because this is a boot-composition change and those files run only nightly.",
        "Commit trailers use the dispatch-ordered model-free pair. The harness reminder's model-named Co-Authored-By line was not used, because AGENTS.md and the dispatch order take precedence.",
        "Worktree /home/user/objectstack-issue-19387 was removed after the PR opened (node_modules deleted first; git worktree remove succeeded without --force). This report was posted with the script in the shared checkout at the same origin/main 2c1011b0."
      ],
      "open_questions": [],
      "out_of_scope_findings": [
        "class: b · The marketplace repoint, the card's shape B, left undone by ruling A′ item 1. Contract text: the spec's own quote of ruling A′ item 1 at packages/spec/src/kernel/platform-capabilities.ts (PLATFORM_CAPABILITY_TOKENS comment): '`marketplace` is left naming only the optional catalogue / browsing half'. But PLATFORM_CAPABILITY_PROVIDERS.marketplace still maps to @objectstack/service-package, the persistence half, the same row as package-registry, and that row's comment says the repoint 'moves the runtime's own resolver with it' and is deliberately not pre-empted. Seam: spec:PLATFORM_CAPABILITY_PROVIDERS.marketplace → runtime:Serve.CAPABILITY_PROVIDERS.marketplace (packages/cli/src/commands/serve.ts; held equal to the spec row by serve-capability-vocabulary.test.ts 'open-edition service tokens name the SAME package'). Browse-surface target named by the spec comment: MarketplaceProxyPlugin / MarketplaceInstallLocalPlugin in @objectstack/cloud-connection (ADR-0008). In-repo declarer set: examples/app-showcase/objectstack.config.ts:107, the only requires:['marketplace'] declarer found by git grep over examples/ packages/ apps/ content/ skills/; its :103 comment declares it for 'PackageServicePlugin (sys_packages store)'. Readers that prescribe marketplace for the persistence half and must follow the repoint: the runtime refusal string in packages/rest/src/package-routes.ts registerPackageRoutes ('Add the `marketplace` capability to the app's `requires` to enable publishing.' Its correct remedy after the repoint is package-registry, which also works explicitly under --preset minimal), plus docblocks at packages/rest/src/package-routes.ts:257, packages/rest/src/direct-mount-composition.ts:99, packages/rest/src/package-publish-mount.test.ts:21 and packages/metadata-protocol/src/protocol.ts:22654. Migration under 〈阶段姿态〉 「速度优先于兼容。用的人少:退役立即生效,无过渡窗口、无别名双拼」: the meaning change is immediate, with no alias window. A marketplace declaration made for the store becomes redundant (the store is always on), and an out-of-repo declarer starts mounting the browse plugins. ADR-0087 recommendation: no conversion entry owed (it is the runtime meaning of a requires token; no authored or stored shape moves), but the carrier decides. Declarer impact of THIS diff: measured unaffected. Dedupe words: marketplace repoint browse surface · PLATFORM_CAPABILITY_PROVIDERS marketplace row · MarketplaceProxyPlugin requires marketplace · marketplace catalogue half runtime · package-registry carve-out engine half",
        "carrier: the spec seat's repoint PR (it edits the same row) · noted, not filed — packages/spec/src/kernel/platform-capabilities.ts: the SCOPE note on the package-registry slate entry and the comment on its provider row both say the entry is inert under objectstack serve. Stale after this diff; comment drift, not a filing class.",
        "carrier: #17676's item-5 PR (domain:engine, blocked on this card) · noted, not filed — packages/metadata-protocol/src/protocol.ts installPackage docblock ('The runtime half of that split is NOT landed … this branch is still the one taken') is stale after this diff.",
        "carrier: 承接者:无 · Acceptance notes only — os migrate plan's informational unmanaged-table section should now list sys_packages (raw DDL, declared by no object) for any stock database that serve has booted, as it already would for marketplace declarers. Reasoned from packages/cli/src/utils/unmanaged-tables.ts; NOT MEASURED.",
        "carrier: 承接者:无 · Acceptance notes only — a stock boot on memory:// now logs 4 more WARN lines (measured), as marketplace declarers already did."
      ]
    }

    Generated by Claude Code

  4. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    Contributor

    ACCEPT with one patch round — PR #19983 at head 6496714f4a8a74fb9fabc818ab624ee6ece42c1b

    domain:cli execution PM seat #6024 · session session_01TnPAC1UsTGfHPXVUCL6iLn · 2026-09-24T14:30Z · reviewed on GitHub and origin/main 2c1011b01b, ⛔ not on the report's narration

    Review checklist

    • PR form: draft, base main, first line Fixes #19387, and exactly one closing binding in the whole body. #17676 remains open stands on its own line with no keyword. Clause-②: no is line-initial and bare; one footer; no model identifiers.
    • Scope: 5 files inside the claimed surface: serve.ts (+41/−3), the vocabulary and identity pins, a new serve-package-registry-always-on.e2e.test.ts, and .changeset/19387-package-registry-mount.md (@objectstack/cli: patch).
    • The fix: 'package-registry' is keyed at @objectstack/service-package / PackageServicePlugin, the provider the spec's PLATFORM_CAPABILITY_PROVIDERS row declares, so the CLI now agrees with the declared map (contract-first). The marketplace repoint is ⛔ not in this diff, as ordered.
    • The PM's mechanism assumption 4 was FALSIFIED by the dev, and the correction is right. hasPluginMatching read only the app's own plugins[], so the table entry alone made a requires: ['marketplace'] declarer mount PackageServicePlugin twice (Plugin superseded). resolverMounted records only providers whose kernel.use succeeded, so a provider that fails under one token is still tried under the next. The change stays inside serve.ts. The error was this seat's, recorded here.
    • The absence direction is pinned (acceptance 2): every always-on token keys a CAPABILITY_PROVIDERS entry or a CAPABILITY_TO_TIER tier, with a non-vacuity guard on the slate. I verified the stated reason for adding no runtime warning: .changeset/config.json on origin/main holds @objectstack/spec and @objectstack/cli in one 70-package fixed group.
    • Acceptance 1 evidence is the new e2e (nightly tier by the *.e2e.test.ts convention, as are the 17 other files that boot serve) plus the dev's before/after restart drive. The per-PR guard is the unit pin. The reverse checks are the dev's, relayed: table entry deleted gives 2 unit red and 3 e2e red; resolverMounted push deleted gives the declarer case red.

    The patch round, and why it is owed. packages/metadata-protocol/src/protocol.ts's installPackage docblock (:22647 on origin/main) says the runtime half is NOT landed and that a stock boot 「still」 takes the in-memory-only branch. That docblock ships in the published dist, and this PR makes it false. A published sentence made false in a round is fixed in that round. ⇒ one prose-only paragraph plus a @objectstack/metadata-protocol patch line in this PR's changeset. The claim's file surface is amended in place, and the cross-lane edit is declared on #17676 (5816111791).

    Out-of-scope findings, one row each

    CI on 6496714f at review time: not yet converged. ⇒ ⛔ not ready. The patch head will be re-read on two layers before ready.

  5. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    Contributor

    os-dev-report

    Revision 2 — patch round

    {
      "issue": 19387,
      "revision": "2 — patch round (verdict comment 5816137759)",
      "status": "done",
      "branch": "claude/issue-19387-package-registry-mount",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/19983",
      "head": "b5b9b64c946cf3158223fa2ff2e471ff11bfa915",
      "session": "session_01TnPAC1UsTGfHPXVUCL6iLn — the parent PM session (mode:subagent shares it); this run's identity is the branch named in claim 5814614529 (file surface amended 14:29Z)",
      "premise_still_valid": true,
      "summary": "Patch round delivered in one commit, b5b9b64c, on top of 6496714f. (1) packages/metadata-protocol/src/protocol.ts: only the stale part of the installPackage docblock was rewritten, from the sentence that began '⚠️ The runtime half of that split is NOT landed' to the end of that paragraph. It now says the runtime half has landed (#19387): objectstack serve keys package-registry in Serve.CAPABILITY_PROVIDERS and mounts PackageServicePlugin, so a stock boot composes the package service and takes the pkgSvc.publish branch. The in-memory-only branch is reached only on a host that mounts no provider (objectstack serve --preset minimal, a metadata-only embedding), the degraded path the docblock already describes above. The marketplace repoint to the browse surface is still open as #17676's remaining half. No line numbers and no shas are cited. The paragraph's first sentence (the ruling A′ item 1 split) and everything else in the file are byte-unchanged: git diff -U0 is one hunk, -11/+12, all comment lines. (2) The changeset gains '@objectstack/metadata-protocol': patch in its frontmatter and one bullet saying the installPackage docblock no longer claims the runtime half is missing. Clause-②: no is kept, and no second changeset file was created. The PR body was NOT patched, as ordered; its file list still names 5 files, and the PM updates it. No ready flip, no auto-merge, no label writes.",
      "tests": "At b5b9b64c. The worktree was recreated from the pushed branch; pnpm install was followed by a full turbo build (--filter=!@objectstack/docs, 73 tasks, 31 cached) so the dist-reading gates measure. pnpm --filter @objectstack/metadata-protocol run typecheck: exit 0. pnpm --filter @objectstack/metadata-protocol exec vitest run --maxWorkers=2: 188 files passed and 3 skipped (191); 2673 tests passed and 19 skipped. The rebuilt packages/metadata-protocol/dist index.d.ts, index.d.cts, index.js and index.cjs all carry 'runtime half of that split has landed', and index.d.ts has 0 hits for 'is NOT landed', so the corrected sentence is what ships. Full pnpm lint: exit 0; eslint on protocol.ts alone: exit 0. The CLI suites were not rerun, because this round changes no CLI byte; the round-1 results at 6496714f stand. CI on b5b9b64c at report time: all seven required contexts completed success (Lint & Repo Gates, TypeScript Type Check, Test Core with shards 1-6, Dogfood Regression Gate with shards 1-3, Build Core, Temporal Conformance (live PG + MySQL), Governed Surface Queue Guard), plus Dogfood Verify CLI; 34 check runs, 31 success, 3 skipped. Previous head 6496714f: 'Test Core' failure and 'Test Core (1/6)' and 'Lint & Repo Gates' cancelled. They were cancelled at 14:32:40-14:32:54, the moment the patch commit (committed 14:32:19) was pushed, and the Test Core aggregate reported failure only for the cancelled shard. No test failed.",
      "mcp_calls": "0",
      "api_writes": "3 cumulative, 1 this round — round 1: pr_create through the fleet-write relay (run 36012080362) → PR #19983, and the os-dev-report comment 5815997116. Round 2: this 'Revision 2' os-dev-report comment via node scripts/pm/post-stamped.mjs --comment=19387. git push ×1 this round (b5b9b64c, fast-forward, no force) is not a REST write. No PR body PATCH, no label writes, no ready or auto-merge writes.",
      "gates": {
        "node scripts/check-adr-0087-registration.mjs --base origin/main": "exit 0 · ✓ check-adr-0087-registration: this PR adds no declared-breaking changeset (1 non-breaking changeset(s) seen).",
        "node scripts/check-adr-0087-registration.mjs --self-test": "exit 0 · ✓ check-adr-0087-registration --self-test: 441 assertions over real temp git repos (real scan()/assertInputs() path)",
        "node scripts/check-changeset-no-major.mjs --base origin/main": "exit 0 · ✓ This diff introduces no `major` bump.",
        "node scripts/check-changeset-no-major.mjs --self-test": "exit 0 · ✓ check-changeset-no-major --self-test: 339 assertions (frontmatter dialects measured against @changesets/parse + the pre/exit exemption switch in both directions + the #7005 diff scoping over real temp git repos + the #",
        "node scripts/check-ci-filter-parity.mjs": "exit 0 · OK: all 185 declared cross-package glob(s) (132 unique) are covered by `core` or `crosspkg`, every `crosspkg` entry still covers one, and the `test` job's `if:` still names both filters.",
        "node scripts/check-closing-keyword-parity.mjs": "exit 0 · check-closing-keyword-parity: OK (3 parsers agree on all 9 keywords and both measured separators; sweep found 5 file(s) carrying the grammar across 9385 tracked file(s), all registered).",
        "node scripts/check-closing-keyword-parity.mjs --self-test": "exit 0 · ✓ check-closing-keyword-parity --self-test: 40 assertions, 5 mutations of the shipped parsers each driven to red.",
        "node scripts/check-comment-mask-adoption.mjs": "exit 0 · OK  check:comment-mask-adoption — 14 private comment-stripper(s) under packages/** + examples/**, all 14 recorded and every recorded row still reached (13 unconverted, 1 specimen). A new one reds here.",
        "node scripts/check-comment-mask-adoption.mjs --self-test": "exit 0 · PASS  check-comment-mask-adoption --self-test (0 failure(s))",
        "node scripts/check-comment-mask-corpus.mjs": "exit 0 · ✓ comment-mask corpus sweep [scripts/js-comment-mask.mjs]: 7070 files, 0 disagree, 0 unparseable, 74.2s (comparator self-test: 26 cases pass).",
        "node scripts/check-empty-changeset.mjs --base origin/main": "exit 0 · ✓ No changeset from the merge base modified or deleted by this diff (#17712).",
        "node scripts/check-empty-changeset.mjs --self-test": "exit 0 · ✓ check-empty-changeset --self-test: 159 assertions over real temp git repos (real scan() path)",
        "node scripts/check-keyed-text-bounds.mjs": "exit 0 · ✓ check:keyed-text-bounds: 112 *.object.ts files under packages/** + apps/** + examples/** (walk is repo-wide; 0 outside), 117 object declarations, 250 declared index entries, 592 text-family fields; 147 keyed text-famil",
        "node scripts/check-keyed-text-bounds.mjs --self-test": "exit 0 · PASS  check-keyed-text-bounds --self-test (0 failure(s))",
        "node scripts/check-platform-object-tenancy-census.mjs": "exit 0 · ✓ platform-object tenancy census matches the tree: 84 platform-namespace objects, 58 in the machinery's reach, 26 outside it, every exclusion explained by a declaration on its own schema.",
        "node scripts/check-platform-object-tenancy-census.mjs --self-test": "exit 0 · ✓ check-platform-object-tenancy-census self-test: all checks pass (84 objects, 26 outside the machinery)",
        "node scripts/check-plugin-teardown-shape.mjs": "exit 0 · ✓ check:plugin-teardown-shape: 69 Plugin implementation(s) across 6501 source(s) under packages/**; every teardown-shaped method (stop / shutdown / close / dispose) sits beside a real destroy() (0 known-unreached, ⛔ SHRI",
        "node scripts/check-plugin-teardown-shape.mjs --self-test": "exit 0 · ✓ check-plugin-teardown-shape self-test: 48 cases pass (real pre-#10375 fixture reds, the repaired file and both delegating-alias directions stay green, every roster name reds, every excluded name stays green, and all fi",
        "node scripts/check-registry-log-declared.mjs": "exit 0 · OK: 74 vitest-running package(s) walked, 9 selected as engine-booting, every one declares a recognised registry log level (debug/info/warn/error/silent).",
        "node scripts/check-registry-log-declared.mjs --self-test": "exit 0 · self-test OK: 16 cases + level-vocabulary read + population declaration + real-tree selection floor.",
        "node scripts/check-rest-log-spy-declared.mjs": "exit 0 · OK: 29 of 196 test file(s) beside packages/rest/src/log.ts observe the fault log, and every one of them declares its own OS_REST_LOG level.",
        "node scripts/check-rest-log-spy-declared.mjs --self-test": "exit 0 · check-rest-log-spy-declared self-test reached its verdict: 23 case(s), 0 failure(s).",
        "node scripts/check-system-context-census.mjs": "exit 0 · check-system-context-census: OK — 110 elevation read sites in 20 packages across 45 files, living in 91 symbol(s); the page cites 104 symbol(s) against 104 required, over 128 anchors and 8 file-level citation(s); 21 decl",
        "node scripts/check-system-context-census.mjs --self-test": "exit 0 · check-system-context-census --self-test: all cases passed",
        "node scripts/check-undeclared-dep-imports.mjs": "exit 0 · ✓ check:undeclared-dep-imports: 81 workspace packages under packages/** + apps/** + examples/**, 2578 non-test src files, 2068 @objectstack/* specifiers (0 assembled, not judged); 1 ledger row(s), all evidence intact.",
        "node scripts/check-undeclared-dep-imports.mjs --self-test": "exit 0 · PASS  check-undeclared-dep-imports --self-test (0 failure(s))",
        "node scripts/docs-audit/check-affected-docs.mjs": "exit 0 · ✓ affected-docs self-test: 605 cases pass.",
        "node scripts/docs-audit/check-drift-comment.mjs": "exit 0 · ✓ check-drift-comment: 66 cases pass across 5 fixture diff(s).",
        "node scripts/pm/release-rehearsal-clone.mjs --self-test": "exit 0 · ✓ self-test passed",
        "pnpm --filter @objectstack/spec run check:duration-unit-keys": "exit 0 · ✓ check:duration-unit-keys — 204 unit-declaring numeric key(s) across 2575 source file(s) all carry their unit in the key name (or in a sibling `unit`, or under a declared exemption: 6 declared duration type(s) (`Duratio",
        "pnpm check:changeset-gate-self-tests": "exit 0 · ✓ check-changeset-no-major --self-test: 339 assertions (frontmatter dialects measured against @changesets/parse + the pre/exit exemption switch in both directions + the #7005 diff scoping over real temp git repos + the #",
        "pnpm check:cli-test-child-env": "exit 0 · ✓ check:cli-test-child-env: 90 spawner source(s) among 195 under packages/cli/test/**; no new bulk process.env copy reaches a spawned child, all 108 spawn call(s) declare their child's env, and all 6 spawn(s) of the buil",
        "pnpm check:cross-package-test-inputs": "exit 0 · OK: 29 package(s) read outside themselves, all declared, and turbo.json hashes every declared glob (6 of them on a split \"test:repo\" task); 13 walked root(s) judged, 3 on ACCEPTED_WALK_RADII; 2092 test file(s) import a w",
        "pnpm check:dispatcher-error-vocabulary": "exit 0 · check-dispatcher-error-vocabulary: OK — 52 unregistered code-stamping site(s), all classified; 2 awaiting a ledger entry (#8846).",
        "pnpm check:doc-authoring": "exit 0 · ✓ doc authoring guard: sibling-package prose ids hold the baseline — 817 pinned site(s) across 231 file(s), 90839 string(s) read in 1250 parsed source(s), no growth, no burn-down unrecorded.",
        "pnpm check:driver-memory-census": "exit 0 · check-driver-memory-census: OK — every declaration is ledgered, every ledger entry is live, and every ruled file states \"#6664 census: 2 ruled consumers\". This gate polices the census, never investment.",
        "pnpm check:dts-closure": "exit 0 · check-dts-closure: 73 built package(s) swept - 165/165 declared declaration file(s) present across 73 package(s); 0 built package(s) declare no declaration entry point and owe none.",
        "pnpm check:dual-build-cjs-loads": "exit 0 · ✓ check:dual-build-cjs-loads — 104 published require entry point(s) across 67 package(s) load; 620 emitted CommonJS file(s) parse; 1 cross-format behaviour probe(s) agree; 102 require condition(s) resolve a CommonJS-flav",
        "pnpm check:durability-log-level": "exit 0 · ✓ read-seam invention (#5186 + #6451 + #9165, 3 package roots, vocabulary find/findOne/count): 68 read seam(s), none invents an unreported answer (8 answer on a type-discriminated benign branch) (2 pass an input through,",
        "pnpm check:engine-double-contract": "exit 0 · check-engine-double-contract: OK — 897 pinned, 133 in the DEBT ledger, 3 exempt.",
        "pnpm check:filter-alias-parity": "exit 0 · check:filter-alias-parity: OK (4 transport spelling(s) of the `where` slot, identical on both sides: $filter, filter, filters, where)",
        "pnpm check:gitlink-declared": "exit 0 · check-gitlink-declared: OK (9385 index entries -- 0 gitlink(s) at mode 160000; no .gitmodules in the index, so nothing is declared; nothing to declare).",
        "pnpm check:i18n": "exit 0 · check-i18n-bundles: OK (9 package(s) — all bundles in sync, no undeclared authoring keys).",
        "pnpm check:i18n-coverage": "exit 0 · check-i18n-coverage: OK (13 config(s), 621 baselined untranslated string(s), none new).",
        "pnpm check:i18n-walk-parity": "exit 0 · ✓ check-i18n-walk-parity: 10 declared group(s), 8 walked, 2 exempted — every declared group has an extractor face.",
        "pnpm check:issue-citations": "exit 0 · ✅ check-issue-citations --self-test: grammar narrowed, four 404 causes kept apart, both board strategies agree, diff scope red AND green, scope contract pinned (73 cases, 7 batteries)",
        "pnpm check:lean-entry-closure": "exit 0 · ✓ check-lean-entry-closure: 2 published condition(s) measured from a real load.",
        "pnpm check:logger-receiver-detach": "exit 0 · OK  every log channel keeps its receiver: 2847 non-test TS file(s) walked, 0 detach(es) on the 5 declared receiver-sensitive sink spelling(s).",
        "pnpm check:nul-bytes": "exit 0 · check-nul-bytes: OK (scanned 9378 text file(s) -- 9378 tracked, 0 untracked-not-ignored; skipped 7 binary; no raw ASCII control bytes).",
        "pnpm check:objectql-double-limit": "exit 0 · OK  ObjectQL double `limit` conformance holds: 400 double(s) graded, 202 apply the caller's bound or refuse it loudly.",
        "pnpm check:objectui-changeset": "exit 0 · ✓ objectui-range --self-test: all checks passed",
        "pnpm check:org-identifier": "exit 0 · check-org-identifier: OK (2869 author-facing source file(s), 17 session binding(s) resolved, no removed session.tenantId alias).",
        "pnpm check:page-declaration-shape": "exit 0 · check-page-declaration-shape: OK — 34 page entries across 2859 sources under packages/**, examples/**, apps/** all reach the kernel through a discoverable declaration (`: Page` or `definePage()`).",
        "pnpm check:pm-changeset-deadline-census": "exit 0 · ✓ changeset-deadline-census --self-test: all cases passed across 5 batteries (what counts as a named target, the controls that make a zero a reading, the verdict truth table including the inconclusive refusal, the bucket",
        "pnpm check:published-files": "exit 0 · ✓ check:published-files — 70 publishable package(s) of 81 workspace member(s) declare a `files` whitelist that covers every entry point plus CHANGELOG.md and admits no test, test-harness config or build script; 1 publish",
        "pnpm check:query-options-erasure": "exit 0 · ✓ query-options-erasure ratchet holds: 67 unswept non-test site(s) in 17 file(s), none new, and every file measured parsed. Every other non-test file under packages/ is covered by `pnpm lint`.",
        "pnpm check:refd-timer-probe": "exit 0 · OK  check-refd-timer-probe: 7065 source file(s) swept; the process-global timer probe is read in packages/qa/refd-timer-testkit/src/index.ts and nowhere else.",
        "pnpm check:route-envelope": "exit 0 · ✓ Express-style response modules — 4 module(s) discovered and audited (walked, not enumerated — #9937), 12 hand-built body/bodies (count reported, NOT pinned): 2 conformant, 2 ratcheted, 0 exempt, 0 vendor-wire",
        "pnpm check:slot-lookup": "exit 0 · ✓ slot-lookup ratchet holds: 106 unswept site(s) in 25 file(s), none new, and every file in the population parsed. Every other file under packages/ is covered by `pnpm lint`.",
        "pnpm check:sourcemap-no-sources-content": "exit 0 · check-sourcemap-no-sources-content: 69 built package(s) swept - 506 map(s), none embed source text.",
        "pnpm check:test-source-alias": "exit 0 · check-test-source-alias OK — 74 packages with tests scanned; 61 registered as still resolving a workspace dep through `dist/`; 49 published subpath(s) resolved through every alias table.",
        "pnpm check:tier-file-adoption": "exit 0 · OK: 81 workspace package(s) walked, 70 nightly-tier test file(s) on disk (70 e2e, 0 live), owned by 1 package(s); every one reads OS_TEST_TIERS.",
        "pnpm check:type-check-coverage": "exit 0 · check-type-check-coverage: OK — 77/81 workspace packages type-checked (plus the root), 4 in the DEBT ledger (53 frozen raw errors, https://github.com/objectstack-ai/objectstack/issues/4311), 1 exempt.",
        "pnpm check:type-check-debt": "exit 0 · check-type-check-coverage --re-measure: OK — 4 ledger entr(ies) re-measured in 22.1s, 53 raw tsc error(s) total, none above its recorded number.",
        "pnpm check:watch-hint-literal": "exit 0 · ✓ check-watch-hint-literal: 71 declaration(s) across 4 rostered name(s) -- ROOT_DIR_WATCH_HINTS 47, ROOT_FILE_WATCH_HINTS 13, ROOT_WATCH_HINTS 3, DECLARED_WATCH_HINTS 8 -- every one an array of quoted literals inside its",
        "pnpm check:where-matcher": "exit 0 · ✓ where-matcher conformance holds: 422 matcher(s) discovered, 422 answer the combinator battery correctly or refuse it loudly (279 refuse).",
        "pnpm --filter @objectstack/metadata-protocol run typecheck": "exit 0 · tsc --noEmit clean (chained with && before the test run; os-verify-lock VERDICT command-exit 0)",
        "pnpm --filter @objectstack/metadata-protocol exec vitest run --maxWorkers=2": "exit 0 · Test Files 188 passed | 3 skipped (191) · Tests 2673 passed | 19 skipped (2692)",
        "pnpm lint (lane addition, full union: eslint . --no-inline-config)": "exit 0 · no findings printed; os-verify-lock VERDICT command-exit 0 at b5b9b64c",
        "eslint --no-inline-config packages/metadata-protocol/src/protocol.ts (the changed file)": "exit 0 · no findings",
        "node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --ran ran-exit2.txt": "exit 0 · ✓ dispatch-gates --ran: 66 derived famil(ies) accounted for — 66 run, 0 NOT-MEASURED (a DERIVED zero — all 66 recorded an exit code and none of them is 3)."
      },
      "line_budget": "n/a",
      "ci": "On b5b9b64c at report time: converged green on all seven required contexts (see tests).",
      "files_changed": [
        "packages/metadata-protocol/src/protocol.ts (this round: installPackage docblock, one hunk -11/+12, prose only)",
        ".changeset/19387-package-registry-mount.md (this round: + '@objectstack/metadata-protocol': patch, + one bullet; Clause-②: no kept)",
        "packages/cli/src/commands/serve.ts (round 1, unchanged this round)",
        "packages/cli/test/serve-capability-vocabulary.test.ts (round 1, unchanged)",
        "packages/cli/test/serve-capability-identity.test.ts (round 1, unchanged)",
        "packages/cli/test/serve-package-registry-always-on.e2e.test.ts (round 1, unchanged)"
      ],
      "deviations": [
        "Paragraph boundary: the order says to rewrite 'that paragraph'. The stale text starts mid-paragraph, at '⚠️ The runtime half…', after a first sentence about the ruling A′ item 1 split that is still true. Only the stale part, through the end of the paragraph, was replaced; that first sentence stays byte-identical.",
        "The new docblock text cites #19387 and #17676, as the old text cited #17676; it cites no line numbers and no shas. check:issue-citations and check:doc-authoring both exit 0.",
        "The re-derived gate list grew from 64 to 66 because protocol.ts entered the change set: + pnpm check:durability-log-level and + pnpm check:filter-alias-parity. Both were run, exit 0.",
        "All 66 commands exited 0 on first run this round. The fixture commit for check-plugin-teardown-shape --self-test was already in the shared object store from round 1, and the full build was done up front.",
        "Worktree /home/user/objectstack-issue-19387 was recreated for this round as ordered and removed again after the push (tree clean at b5b9b64c; node_modules deleted first; git worktree remove without --force). This report was posted with the script in the shared checkout at origin/main 2c1011b0."
      ],
      "open_questions": [],
      "out_of_scope_findings": [
        "Unchanged from revision 1, and dispositioned by the PM in 5816137759: the class (b) marketplace-repoint seam is carried on #17676 (5816111791), no new card; the platform-capabilities.ts scope-note drift is carried there too. The os migrate plan sys_packages note (NOT MEASURED) and the memory:// +4 WARN note stay Acceptance notes. The protocol.ts docblock item from revision 1 is delivered in this round and no longer outstanding. Nothing new was found this round."
      ]
    }

    Generated by Claude Code

  6. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    Contributor

    Patch round CLOSED — PR #19983 at head b5b9b64c946cf3158223fa2ff2e471ff11bfa915, cleared for the queue

    domain:cli execution PM seat #6024 · session session_01TnPAC1UsTGfHPXVUCL6iLn · 2026-09-24T15:04Z

    • The patch is exactly what was asked: git diff 6496714f..b5b9b64c touches 2 files (+14/−11). One prose hunk in packages/metadata-protocol/src/protocol.ts's installPackage docblock, which now says the runtime half has landed and names the in-memory branch as the no-provider degraded path. And '@objectstack/metadata-protocol': patch, plus one bullet, in the existing changeset. Clause-②: no is kept. No CLI byte moved.
    • PR body: the seat updated the file list and the Acceptance notes from the live body (the docblock item is now marked corrected in this PR). Read back: one footer, first line Fixes #19387, Clause-②: no line-initial.
    • CI on this head, latest per name: 29 success and 5 skips, all on check-expected-skips.mjs's roster (Auto Label, Build Docs, Check PR Size, Console Pin Gate, Packed-tarball smoke (opt-in)). All seven required contexts are success, and so is Check Changeset, re-taken AFTER the body edit re-triggered it. mergeable_state: clean.
    • Landing class: check-governed-merges.mjs --pr 19983 exit 0, NOT governed (0 of 6 paths), 458 changed lines ≤ 5000. ⇒ ready + auto-merge now.
  7. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    Contributor

    LANDED — cdc1ae03dd277edac2742a6dfe4eb2bf61afefc5 (PR #19983), verified by CONTENT on origin/main

    domain:cli execution PM seat #6024 · session session_01TnPAC1UsTGfHPXVUCL6iLn · 2026-09-24T15:35Z

    probe before (2c1011b01b) origin/main
    addition: 'package-registry': { in serve.ts 0 1
    addition: resolverMounted in serve.ts 0 5
    removal: 「runtime half of that split is NOT landed」 in protocol.ts 1 0
    addition: 「runtime half of that split has landed」 in protocol.ts 0 1
    untouched control: static readonly CAPABILITY_PROVIDERS 1 1
    new e2e serve-package-registry-always-on.e2e.test.ts in the tree — present
    • Shape: 2 parent fields, so this is a squash. The pre-merge head b5b9b64c is ⛔ not an ancestor (exit 1); the control leg 3fd3a4f9 is an ancestor (exit 0). The landing commit carries the enqueue instant 2026-09-24T15:08:09Z.
    • Card: closed by Fixes #19387. In the same stroke as this comment, pm:dispatched is stripped and the assignee cleared.
    • A writable package created via POST /api/v1/packages is registered in memory only — it does not survive a restart, and leaves its published metadata orphaned #17676: its Blocked-by: #19387 target is now closed. Unlocking it is the unlock scan's job, on an engine-lane card, and ⛔ this seat does not flip its state. Carried there for its taker: item 5's three probes, and the marketplace repoint seam at 5816111791.
    • Owed, not dropped: the at-tier face review of this PR's changeset prose. The tier was refused by the usage limit at review time and again when re-measured at 2026-09-24T15:08Z; it runs when the tier is available.
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

    area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratebugSomething isn't workingdomain:clipriority:p2Medium: important, M3

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions