Repository navigation
feat(runtime): a package export names each connector map it withheld; install-local names each as incomplete - #29746
Conversation
…nstall-local names each as incomplete Claude-Session: https://claude.ai/code/session_01JQwxbYXRMR5S5B7JSmKkV7 Co-authored-by: Claude <noreply@anthropic.com>
…es name them; changeset Claude-Session: https://claude.ai/code/session_01JQwxbYXRMR5S5B7JSmKkV7 Co-authored-by: Claude <noreply@anthropic.com>
… withheldMaps describe Claude-Session: https://claude.ai/code/session_01JQwxbYXRMR5S5B7JSmKkV7 Co-authored-by: Claude <noreply@anthropic.com>
…-vrj8cl # Conflicts: # packages/runtime/src/domains/packages.ts
…main Claude-Session: https://claude.ai/code/session_01JQwxbYXRMR5S5B7JSmKkV7 Co-authored-by: Claude <noreply@anthropic.com>
#29617 Claude-Session: https://claude.ai/code/session_01JQwxbYXRMR5S5B7JSmKkV7 Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 3 package(s): 2 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
What this run could not see
Coarse fallback — 176 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 99b84e01cdcdb13d00eb8c468626b5d489bd4d8e && git checkout 99b84e01cdcdb13d00eb8c468626b5d489bd4d8e
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin be6b15c7cb309cf89358332e5927b4763e9c82a2 85d56fc4e07d81342f9b269d77ec4772605e5868 && git checkout -B drift-repro be6b15c7cb309cf89358332e5927b4763e9c82a2 && git merge --no-ff 85d56fc4e07d81342f9b269d77ec4772605e5868
node scripts/docs-audit/affected-docs.mjs --json be6b15c7cb309cf89358332e5927b4763e9c82a2
|
|
domain:server#5 · os-warren · session_01JQwxbZUR3xvHyDPCjNL5P4 Contract-review-claim: session_01JQwxbZUR3xvHyDPCjNL5P4 · head c5a3414 · 2026-11-03T03:16Z |
|
domain:server#5 · os-warren · session_01JQwxbZUR3xvHyDPCjNL5P4 Contract reviewServed-tier: Inputs read: card #29342 (body + all 11 comments, rulings 6578196369 / 6592752231 included), PR #29746 body, file list and net diff ① Derived judgments
② Semver level
③ Boundary flags
④ Design judgment
Cited code read, not reviewed (the lane seat's ACCEPT at Implemented-by: VERDICT: PASS |
…ent export as declared ahead The nav arm is served by #28722's server slice (#29742); the paragraph now names PackageExportBundleSchema (#28914) alone. Reference doc regenerated. Claude-Session: https://claude.ai/code/session_01JQwxbYXRMR5S5B7JSmKkV7 Co-authored-by: Claude <noreply@anthropic.com>
|
domain:server#5 · os-warren · session_01JQwxbZUR3xvHyDPCjNL5P4 Contract reviewServed-tier: Delta record: one commit on top of ① Derived judgments
② Semver level
③ Boundary flags
④ Design judgment
Implemented-by: VERDICT: PASS |
…-vrj8cl # Conflicts: # packages/spec/src/api/package-lifecycle.zod.ts
…he reference after merging main With #29742 (nav arm), #29755 (whole-deployment export) and this change (withheldMaps) all served, no member of package-lifecycle.zod.ts is declared ahead of its producer. Claude-Session: https://claude.ai/code/session_01JQwxbYXRMR5S5B7JSmKkV7 Co-authored-by: Claude <noreply@anthropic.com>
|
domain:server#5 · os-warren · session_01JQwxbZUR3xvHyDPCjNL5P4 Contract reviewServed-tier: Delta record: two commits on top of ① Derived judgments
② Semver level
③ Boundary flags
④ Design judgment
Cited code read, not reviewed: Implemented-by: VERDICT: PASS |
|
domain:server#5 · os-warren · session_01JQwxbZUR3xvHyDPCjNL5P4 席位核对ACCEPT ·
|
Requested by Warren · project thread
Fixes #29342
Clause-②: yes (widening)
Metadata-protocol: none
One narrowing arm, named here in prose as the seat directed (amendment 6592752231):
POST /marketplace/install-localnow refuses awithheldMapsvalue that the export's own declaration refuses, answeringPLUGIN_MANIFEST_INVALIDbefore any write in either mode. Before this change the door ignored the key whatever its value. No producer wrote the key before this PR, so only a hand-written list can be refused.维护者速读
GET /packages/:id/export)现在写出withheldMaps(整库导出GET /packages/export的每个条目同样带上,因其逐包复用同一导出),逐条列出被整张扣下的连接器 header/env 表;install-local 的托管与非托管两种安装都在应答里逐条点名这些不完整的表,并打一条 warn。withheldMaps新增 400 拒绝。回滚即还原本 PR。packages/runtime/src/domains/packages.ts的withheldConnectorMaps;packages/cloud-connection/src/marketplace-install-local-plugin.ts的judgeWithheldMaps及两处应答;packages/spec/src/api/package-lifecycle.zod.ts的描述改动。pnpm --filter @objectstack/runtime exec vitest run src/domains/packages-export-withheld-maps.test.ts,预期 6 条全绿,第一条列出四个位置。What changes
withheldMaps.assemblePackageManifest(runtimepackages.ts) now lists{ type: 'connector', name, path }for every connector map the served read withheld whole. These are the four positionsPackageExportManifestSchema.withheldMapsdeclares:providerConfig.headers,providerConfig.defaultHeaders,providerConfig.transport.headersandproviderConfig.transport.env. The new hunk sits at the end of the function, after thelabel,namespaceanddependencieslines (the last two from spec + runtime: a package export carries no namespace and no dependencies, so a reinstalled .custom pair lands under the wrong namespace without its base edge; declare both on PackageExportManifestSchema and emit them #29617), apart from the per-packagedeclaresOverrideOffilter that fix(runtime): the base export serves the base's own document while a .custom override of it is live #29687 (card packages: a published dashboard or report override removes the item from the base's export, where ADR-0146 D8 item 3 says the base export is unchanged #29649) edits.getMetaItemForExecution({ type: 'connector', name, packageId }), and handed to the sameconnectorredactor the served read ran (getMetadataTypeRedactor('connector')). Every position itsredactedKeysnames that the declaration lists is written. That face's docblock allows a door to read a decision off it, as long as no byte of the body reaches the response. Only the position leaves: no header or variable name, no value.connectoris not an overridable type: it has no row inOVERRIDE_TYPE_CLASSIFICATION, and the write gate refuses an override declaration on a type outside it. So under the package's own id, the by-name read answers the package's own connector, the one the per-package list served.POST /marketplace/install-local(cloud-connection, the door the Studio import button posts to) parses the body'swithheldMapsthroughPackageExportManifestSchema.shape.withheldMapsbefore any write. The managed and unmanaged answers each gainwithheldMaps, the list as the export wrote it, and onewarnline names every map. The key is left out when the body carries no list, so that answer's key set is unchanged. The package is accepted and never refused because a map is incomplete (ruling A).[PLANNED — not yet served]marker is dropped fromwithheldMaps' describe, and its pin inpackage-lifecycle.test.tsflips to assert that the marker is absent. The module and schema docblocks now say the key is served. The comment on thedoorrow inkernel/unmanaged-install.tssays the same (comment only, approved in amendment 6592752231).content/docs/references/api/package-lifecycle.mdxis regenerated bycheck:generated --fix. After merging feat(runtime): the customizations read serves the nav contributions other packages add to a base's apps #29742 (nav served) and feat(runtime,client,cli): export a deployment's whole ontology as installable packages in one read (GET /packages/export, os package export) #29755 (packages: a tenant exports its whole ontology — every installed package, its.custompair and environment customizations — as installable packages for the open runtime (os package export+ the read it calls) #28914, the whole-deployment bundle served), no member ofpackage-lifecycle.zod.tsis declared ahead any more, so the header's declared-ahead paragraph is removed (85d56fc) and the mdx regenerated.29342-export-withheld-connector-maps.md, patch for runtime, cloud-connection and spec, carrying both declaration lines and the narrowing arm in prose.Tests
packages/runtime/src/domains/packages-export-withheld-maps.test.ts(6 tests). It uses the real dispatcher, with a protocol double whose served list runs the realconnectorredactor. It checks: all four positions in order; the exported items as served, with no header name or value in the manifest; a connector with no map, or with a cleared map, is not listed; a package with no connectors asks the face nothing; a protocol without the face, and a missing body, each fail the export.packages/cloud-connection/src/marketplace-install-local-withheld-maps.test.ts(7 tests), at the plugin's real route. Managed and unmanaged answers each name the list, with one warn line. A body without the list gets no key and no warn. Three malformed lists are refusedPLUGIN_MANIFEST_INVALID, 400, in both modes, with nothing registered, ledgered or imported.packages/qa/dogfood/test/export-withheld-connector-maps.dogfood.test.ts(4 tests) runs on the real showcase composition. It installs a package with three connectors, two carrying header maps, then exports it. The export lists the three maps and carries no header name or value. A managed re-install of the export names them. On a second boot that never held the package, an unmanaged install of the export also names them.Red first, by reverse verification on the base source (744211f)
git restore --source=744211fcof the two runtime and cloud-connection source files, with on-disk marker counts0 0and runtime and cloud-connection rebuilt. Thenablation-dist-preflightconfirmed thatwithheldConnectorMapsis absent frompackages/runtime/dist.Restored with
git restore --source=HEAD --staged --worktree,git status --porcelainempty, rebuilt, preflight found the marker present again, and the dogfood ran 4/4 green.Ablation of the narrowing arm (seat ask)
node scripts/ablation-replace.mjsturnedif (!declared.success)intoif (!declared.success && false)injudgeWithheldMaps: anchor 1 → 0, blob f2cf4131 → 84f0fc0a. Result: 3 failed | 4 passed, and the failures were exactly the threePLUGIN_MANIFEST_INVALIDcases. Restored: the blob equals HEAD, andgit diff HEADis empty.Acceptance notes
typeorinstallModes, so it does not import unmanaged as written. Measured on the showcase:importUnmanagedPackagerefused the bare export withmanifest.type: Invalid option. The per-package export writes onlyid,name,version,label,namespace,dependenciesand its collections. This belongs to the export's manifest-key family; carrier: packages: a tenant exports its whole ontology — every installed package, its.custompair and environment customizations — as installable packages for the open runtime (os package export+ the read it calls) #28914. The dogfood adds the two keys an operator adds before importing an export as a copy, and its header says so.VALIDATION_ERRORansweredThe unmanaged install of 'com.dogfood.withheldmaps' failed; the reason is in the server log., and the server log had no line with the reason.installUnmanagedlogs only whenresolved.status >= 500. Reported to the seat for filing (class a). Not fixed here. Filed by the seat as cloud-connection: an unmanaged install-local refused 4xx tells the operator "the reason is in the server log", but nothing is logged below 500 #29822.headers(credential: 'map') are dropped in the same silent way. Ruling A keeps them out of scope.assemblePackageManifest. It landed at 33ee9aa and is merged into this branch (009c0b7). After the merge, this PR's hunk is still separate from itsdeclaresOverrideOffilter. feat(runtime): the customizations read serves the nav contributions other packages add to a base's apps #29742 (seat 3) and feat(runtime,client,cli): export a deployment's whole ontology as installable packages in one read (GET /packages/export, os package export) #29755 (packages: a tenant exports its whole ontology — every installed package, its.custompair and environment customizations — as installable packages for the open runtime (os package export+ the read it calls) #28914, seat 4) landed after it and are merged in (c5f0877 at b3d1415).assemblePackageExportBundlecomposes the per-package export, so each bundle entry carrieswithheldMapstoo;PackageExportBundleSchema.packagesisPackageExportManifestSchema[], which already declares the key.Verification
Unit suites, typecheck, gates and lint below were measured at
583fce44, before the merge, and re-run at headc5a34147, after mergingorigin/main(33ee9aa). Post-merge figures are given where they differ.pnpm --filter @objectstack/runtime test: 530 files, 8518 passed, 19 skipped; after the merge, 532 files, 8529 passed, 19 skipped.pnpm --filter @objectstack/cloud-connection test: 68 files, 820 passed, the same after the merge. Specpackage-lifecycle.test.tsandunmanaged-install.test.ts: 63 passed; after the merge, 67 passed. Dogfood file: 4/4 after the merge.pnpm --filter @objectstack/runtime --filter @objectstack/cloud-connection typecheck: exit 0.pnpm --filter @objectstack/spec check:generated:check:docswas stale and was fixed with--fix(one artifact). The other 13 were up to date.node scripts/pm/dispatch-gates.mjs --commands: 105 families. All 105 exit 0, three of them after their prerequisites were met: the clone was unshallowed forcheck-plugin-teardown-shape --self-test, and the client and plugin packages were built forcheck:skill-examplesandcheck:dual-build-cjs-loads.--ranreconciliation: 105 derived, 105 run, 0 NOT-MEASURED, 0 UNRUN.pnpm lint: exit 0.!and Clause-② has no(narrowing)arm.Re-run at head
85d56fc4(after mergingorigin/mainb3d1415): typecheck for spec, runtime and cloud-connection exit 0; spec package-lifecycle and unmanaged-install 67 passed; runtime 535 files, 8560 passed, 19 skipped; cloud-connection 68 files, 820 passed; dogfood file 4/4;dispatch-gates --commands105 derived, 105 exit 0,--ran105/105, 0 NOT-MEASURED.Human Minimum
packages/specholds no runtime logic.pnpm lintpasses.main, one pull request.packages/spectouched: its generated artifacts are regenerated and committed.content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.🤖 Generated with Claude Code
https://claude.ai/code/session_01JQwxbYXRMR5S5B7JSmKkV7
Generated by Claude Code