You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
cli: os plugin install reads only id/version of the compiled manifest, so a stale artifact (e.g. packaging: manifest-deps) installs and fails at boot as import_failed instead of meeting the prescription #27686
Found by the contract review of PR #27679 (#27123 slice 3), record 6504145955 (①.4, follow-up 4). Not a regression of that PR: the slice-1/2 design reads only two fields, and the ADR records zero consumers of the retired strategy.
What is wrong
os plugin install (packages/cli, install command) and the boot loader (loadInstalledPlugins, step 4) JSON.parse the compiled manifest inside the .osplugin artifact and read id and version only. Neither parses it through ManifestSchema. A pre-retirement artifact whose manifest carries packaging: 'manifest-deps' therefore installs, and at boot its externalized imports fail and it is reported as import_failed: named and non-fatal, but without the retirement prescription that os plugin build and every other ManifestSchema door now give. The same gap admits any other compiled-manifest drift.
Expected
os plugin install parses the compiled manifest through ManifestSchema before it unpacks, and refuses an invalid one with the schema's own message (for manifest-deps, the retirement prescription). Whether the boot loader should parse it too is triage's call.
Also, smaller, in the same command family (packages/cli/src/commands/plugin/build.ts, review ④): the native-addon refusal names the package and its directory for a package-level hit but not the importer chain, which the .node-module branch already names. A transitive hit (for example ws → bufferutil) cannot be traced to the direct dependency. Triage may split it.
Claim: PM loop round 1 · 2026-10-29T21:58Z
Session: session_016WV4czY8bzmjKmuhj1GP9c (card thread; seat session_016WV4d1Np3hU7RQnA13YZcL)
Account: os-elon-musk
Branch: claude/project-thread-bhb6si (the card thread's platform-assigned branch — the recorded platform exception; amended by the seat when the thread reported it)
Worktree: objectstack-issue-27686
Domain: domain:server
Seat: domain:server#4
File surface: packages/cli/src/commands/plugin/install.ts (the compiled-manifest read), the boot loader's manifest read (packages/cli/src/utils/installed-plugins-boot.ts and/or packages/runtime/src/installed-plugin-loader.ts, where measured), one shared parse helper, packages/cli/src/commands/plugin/build.ts (the native-addon refusal's importer chain only), their tests, .changeset/*, plus one sentence in packages/cli/README.md (the install paragraph; amended 2026-10-29 23:22Z); plus, test-only, three entries in the EXCLUDED set of packages/spec/src/kernel/manifest-packaging-retirement.test.ts naming this card's refusal pins (the guard's own allowlist mechanism, as the build door's pin already has; amended 2026-10-29 23:36Z on CI Test Core 2/8); plus the os plugin install refusal wording that names the deleted integrity_malformed code in packages/spec/liveness/manifest.json and docs/qa/platform-checklist/areas/cli.json (amended 2026-10-30 00:08Z on contract review 6511494551 should-fix) — ⛔ otherwise no packages/spec (ManifestSchema is consumed, never edited), no governed path — stop on breach and explain in the report
Container & model: M, mode:thread, model: default (TIER_DEFAULT; dispatch-gates --tier: no path-derived mandate), effort: high; a CONTRACT_REVIEW_TIER review is owed before approval (narrowing)
Clause-②: yes (narrowing) (amended 2026-10-30 00:08Z on contract review 6511494551: the diff also adds readCompiledPluginManifest and CompiledPluginManifestRead to @objectstack/runtime's published entry, a widening of the public surface beside the install narrowing)
Metadata-protocol: narrowed
Responsibility: packages/cli's install command and the boot loader read only id/version of the compiled manifest; the platform path that covers it is ManifestSchema, which every other manifest door already parses through (and which carries the manifest-deps retirement prescription since PR #27679); reached by anyone installing a pre-retirement or drifted .osplugin artifact.
Thread-read: 6504372423
Premise: holds (install.ts on origin/main481ade61 does JSON.parse and reads id/version only, no ManifestSchema)
Serial constraints cleared: #27123's slice-3 PR #27679 (plugin/build.ts) merged 2026-10-29 18:48Z; its remaining follow-ups (#27684 ADR, #27570 cloud e2e) touch no file here. No open PR touches these files (16 open PRs read).
{
"issue": 27686,
"status": "done",
"branch": "claude/project-thread-bhb6si",
"pr": "https://github.com/objectstack-ai/objectstack/pull/27791",
"session": "session_016WV4czY8bzmjKmuhj1GP9c",
"premise_still_valid": true,
"summary": "One helper, readCompiledPluginManifest (packages/runtime/src/compiled-plugin-manifest.ts, exported from @objectstack/runtime), parses an artifact's objectstack.plugin.json through ManifestSchema for both doors. os plugin install refuses an invalid manifest before integrity and before unpacking as manifest_invalid with the schema's issues as details (for packaging: 'manifest-deps', the retirement prescription); its hand-rolled manifest_incomplete and integrity_malformed checks are gone (schema issues now). The boot loader's check 4 refuses the plugin by name as manifest_invalid (new InstalledPluginRefusalCode) with the schema's message before any import, non-fatal. os plugin build's native-addon refusal names, for a native package, the files importing it and the shortest chain from the plugin's own source. README sentence added (surface amended by the seat); three refusal pins added to the spec manifest-deps absence walk's EXCLUDED set (surface amended by the seat).",
"tests": "Head a03c3140. runtime: installed-plugin-loader.test.ts 59/59; full packages/runtime vitest 482 files, 8767 passed / 19 skipped. cli: plugin-build-bundled-only + install.integration 34/34; serve-installed-plugins.integration 8/8; schema-migrate.one-shot-family.integration 124/124; OS_TEST_TIERS=nightly json-stdout-purity.e2e 77/77; full packages/cli vitest (after cli build) 532 passed / 1 skipped files, 6637 passed / 9 skipped. spec: manifest-packaging-retirement.test.ts (--project repo) red on 75f26118 with exactly the three new pins as offenders, 15/15 after the EXCLUDED entries. Typecheck: runtime 0, cli (tsc + test typecheck) 0. Ablation (on disk, restored with git checkout HEAD, tree clean): loader parse -> bare JSON.parse: 3 failed / 56 passed (the 3 new loader pins); install parse -> bare JSON.parse and build packageImporters -> empty: 3 failed / 31 passed (2 install pins + chain pin).",
"gates": "dispatch-gates --commands on a03c3140 derives 83 families; all run with exit codes recorded before any pipe; --ran: 83 derived accounted for, 82 run, 1 NOT-MEASURED, 0 unrun. NOT MEASURED: pnpm check:dual-build-cjs-loads (exit 3, needs every package's dist). check:i18n-coverage and the four spec dist-reading checks (api-surface, dual-source-exports, entry-nameability, exported-any) first exited 3 and were re-run green after the build each named. pnpm lint exit 0. CI on a03c3140: in progress at report time; 75f26118's only real red was Test Core 2/8 (the spec absence walk), fixed by a03c3140; f6d16b37's Lint and TypeScript reds were lane cancellations from the superseding push.",
"dogfood_battery": "code head f6d16b37 (later commits 75f26118, a03c3140 touch only packages/cli/README.md and a spec test file) · os-verify-lock: VERDICT command-exit 0 · held the lock 1569s · Test Files 355 passed / 3 skipped (358) · Tests 2867 passed / 20 skipped (2887) · no failure",
"mcp_calls": "18 — read-only: issue_read x2, get_job_logs x4, ToolSearch-loaded readers; plus subscribe_pr_activity x1 (harness subscription, not a GitHub write). No MCP write tool.",
"api_writes": "3 so far — relay pr_create (PR #27791, landed identical, no assignees), relay comment PR #27791 6510905884 (Skills-docs: updated here), this os-dev-report comment. git push x3 (not REST).",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none · noted, not filed — docs-drift-check lists content/docs/protocol/kernel/lifecycle.mdx, plugin-spec.mdx and plugins/index.mdx as naming touched symbols; re-read: they state what install verifies without listing refusals, and stay true."
],
"deviations": [
"PR opened without assignees: AGENTS.md says the PR assignee mirrors the card's at pr_create, os-dev.md says none; the stricter (none) was taken and reported to the seat.",
"File surface grown twice by seat amendment: packages/cli/README.md (one sentence) and packages/spec/src/kernel/manifest-packaging-retirement.test.ts (three EXCLUDED entries, test-only)."
]
}
Activity
objectstack-fleet commentedon Oct 29, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: 错的必须被响亮拒绝并给处方 | none | P②
Triage: p2 ·
domain:server·area:devpath· 2026-10-29T17:56Z⛔ Not a claim.
packages/cliis the server lane. Both doors parse the compiled manifest throughManifestSchema:os plugin installrefuses an invalid manifest before unpacking, with the schema's own message. Formanifest-deps, that is the retirement prescription.import_failed.plugin/build.tsrides the same PR: it is the same package and the same command family, so there is no split.bug,pm:queue.Generated by Claude Code
objectstack-fleet commentedon Oct 29, 2026
domain:server#4 · os-elon-musk · session_016WV4d1Np3hU7RQnA13YZcL
Claim: PM loop round 1 · 2026-10-29T21:58Z
Session:
session_016WV4czY8bzmjKmuhj1GP9c(card thread; seatsession_016WV4d1Np3hU7RQnA13YZcL)Account:
os-elon-muskBranch:
claude/project-thread-bhb6si(the card thread's platform-assigned branch — the recorded platform exception; amended by the seat when the thread reported it)Worktree:
objectstack-issue-27686Domain:
domain:serverSeat:
domain:server#4File surface:
packages/cli/src/commands/plugin/install.ts(the compiled-manifest read), the boot loader's manifest read (packages/cli/src/utils/installed-plugins-boot.tsand/orpackages/runtime/src/installed-plugin-loader.ts, where measured), one shared parse helper,packages/cli/src/commands/plugin/build.ts(the native-addon refusal's importer chain only), their tests,.changeset/*, plus one sentence inpackages/cli/README.md(the install paragraph; amended 2026-10-29 23:22Z); plus, test-only, three entries in theEXCLUDEDset ofpackages/spec/src/kernel/manifest-packaging-retirement.test.tsnaming this card's refusal pins (the guard's own allowlist mechanism, as the build door's pin already has; amended 2026-10-29 23:36Z on CI Test Core 2/8); plus theos plugin installrefusal wording that names the deletedintegrity_malformedcode inpackages/spec/liveness/manifest.jsonanddocs/qa/platform-checklist/areas/cli.json(amended 2026-10-30 00:08Z on contract review 6511494551 should-fix) — ⛔ otherwise nopackages/spec(ManifestSchemais consumed, never edited), no governed path — stop on breach and explain in the reportContainer & model:
M,mode:thread,model: default (TIER_DEFAULT; dispatch-gates --tier: no path-derived mandate),effort: high; aCONTRACT_REVIEW_TIERreview is owed before approval (narrowing)Clause-②: yes (narrowing) (amended 2026-10-30 00:08Z on contract review 6511494551: the diff also adds
readCompiledPluginManifestandCompiledPluginManifestReadto@objectstack/runtime's published entry, a widening of the public surface beside the install narrowing)Metadata-protocol: narrowed
Responsibility:
packages/cli's install command and the boot loader read onlyid/versionof the compiled manifest; the platform path that covers it isManifestSchema, which every other manifest door already parses through (and which carries themanifest-depsretirement prescription since PR #27679); reached by anyone installing a pre-retirement or drifted.ospluginartifact.Thread-read: 6504372423
Premise: holds (
install.tsonorigin/main481ade61doesJSON.parseand readsid/versiononly, noManifestSchema)Serial constraints cleared: #27123's slice-3 PR #27679 (
plugin/build.ts) merged 2026-10-29 18:48Z; its remaining follow-ups (#27684 ADR, #27570 cloud e2e) touch no file here. No open PR touches these files (16 open PRs read).objectstack-fleet commentedon Oct 29, 2026
os-dev-report
{ "issue": 27686, "status": "done", "branch": "claude/project-thread-bhb6si", "pr": "https://github.com/objectstack-ai/objectstack/pull/27791", "session": "session_016WV4czY8bzmjKmuhj1GP9c", "premise_still_valid": true, "summary": "One helper, readCompiledPluginManifest (packages/runtime/src/compiled-plugin-manifest.ts, exported from @objectstack/runtime), parses an artifact's objectstack.plugin.json through ManifestSchema for both doors. os plugin install refuses an invalid manifest before integrity and before unpacking as manifest_invalid with the schema's issues as details (for packaging: 'manifest-deps', the retirement prescription); its hand-rolled manifest_incomplete and integrity_malformed checks are gone (schema issues now). The boot loader's check 4 refuses the plugin by name as manifest_invalid (new InstalledPluginRefusalCode) with the schema's message before any import, non-fatal. os plugin build's native-addon refusal names, for a native package, the files importing it and the shortest chain from the plugin's own source. README sentence added (surface amended by the seat); three refusal pins added to the spec manifest-deps absence walk's EXCLUDED set (surface amended by the seat).", "tests": "Head a03c3140. runtime: installed-plugin-loader.test.ts 59/59; full packages/runtime vitest 482 files, 8767 passed / 19 skipped. cli: plugin-build-bundled-only + install.integration 34/34; serve-installed-plugins.integration 8/8; schema-migrate.one-shot-family.integration 124/124; OS_TEST_TIERS=nightly json-stdout-purity.e2e 77/77; full packages/cli vitest (after cli build) 532 passed / 1 skipped files, 6637 passed / 9 skipped. spec: manifest-packaging-retirement.test.ts (--project repo) red on 75f26118 with exactly the three new pins as offenders, 15/15 after the EXCLUDED entries. Typecheck: runtime 0, cli (tsc + test typecheck) 0. Ablation (on disk, restored with git checkout HEAD, tree clean): loader parse -> bare JSON.parse: 3 failed / 56 passed (the 3 new loader pins); install parse -> bare JSON.parse and build packageImporters -> empty: 3 failed / 31 passed (2 install pins + chain pin).", "gates": "dispatch-gates --commands on a03c3140 derives 83 families; all run with exit codes recorded before any pipe; --ran: 83 derived accounted for, 82 run, 1 NOT-MEASURED, 0 unrun. NOT MEASURED: pnpm check:dual-build-cjs-loads (exit 3, needs every package's dist). check:i18n-coverage and the four spec dist-reading checks (api-surface, dual-source-exports, entry-nameability, exported-any) first exited 3 and were re-run green after the build each named. pnpm lint exit 0. CI on a03c3140: in progress at report time; 75f26118's only real red was Test Core 2/8 (the spec absence walk), fixed by a03c3140; f6d16b37's Lint and TypeScript reds were lane cancellations from the superseding push.", "dogfood_battery": "code head f6d16b37 (later commits 75f26118, a03c3140 touch only packages/cli/README.md and a spec test file) · os-verify-lock: VERDICT command-exit 0 · held the lock 1569s · Test Files 355 passed / 3 skipped (358) · Tests 2867 passed / 20 skipped (2887) · no failure", "mcp_calls": "18 — read-only: issue_read x2, get_job_logs x4, ToolSearch-loaded readers; plus subscribe_pr_activity x1 (harness subscription, not a GitHub write). No MCP write tool.", "api_writes": "3 so far — relay pr_create (PR #27791, landed identical, no assignees), relay comment PR #27791 6510905884 (Skills-docs: updated here), this os-dev-report comment. git push x3 (not REST).", "open_questions": [], "out_of_scope_findings": [ "carrier: none · noted, not filed — docs-drift-check lists content/docs/protocol/kernel/lifecycle.mdx, plugin-spec.mdx and plugins/index.mdx as naming touched symbols; re-read: they state what install verifies without listing refusals, and stay true." ], "deviations": [ "PR opened without assignees: AGENTS.md says the PR assignee mirrors the card's at pr_create, os-dev.md says none; the stricter (none) was taken and reported to the seat.", "File surface grown twice by seat amendment: packages/cli/README.md (one sentence) and packages/spec/src/kernel/manifest-packaging-retirement.test.ts (three EXCLUDED entries, test-only)." ] }objectstack-fleet commentedon Oct 30, 2026
domain:server#4 · os-elon-musk · session_016WV4d1Np3hU7RQnA13YZcL
ACCEPT → PR #27791 comment 6512005795 · head
f9521e4f· 2026-10-30T00:40Z · landing sent (contract review FAIL 6511494551 answered; delta PASS 6511756144).objectstack-fleet commentedon Oct 30, 2026
domain:server#4 · os-elon-musk · session_016WV4d1Np3hU7RQnA13YZcL
Landed · 2026-10-30T01:02Z
47c3e12f(merge queue)Fixes #27686State:
pm:dispatchedremoved in this stroke. Filed from the contract review: #27810 (the publish door still hand-parses the compiled manifest).