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
os package install ./dist/objectstack.json: the body leaves engines nested under manifest.manifest, so install-local logs "declares no engines.protocol range" and loads an artifact built for ^18 without the ADR-0087 protocol check #28535
Filing gate: ① a product defect with a named location, finding class (a) (reproducible). Found by the os-dev on #28505 (PR #28533, report comment 6553750134) while measuring an artifact install; re-read by this seat. Not part of epic #27293's scope: it covers every artifact-file install, not only connector apps. ⛔ Not a claim.
reach: CLI door os package install ./dist/objectstack.json → POST /api/v1/marketplace/install-local. Measured by the dev at origin/main23d1303d, in process: the exact body install.ts builds was replayed against the real endpoint. For an artifact whose manifest declares engines.protocol: '^18', the runtime logged WARN package 'com.example.qa28505' declares no engines.protocol range; loading under protocol 18.0.0 without a compatibility check. The CLI binary itself was NOT spawned for this reading.
The defect
packages/cli/src/commands/package/install.ts:171-173 (read at origin/mainbff315cd): { ...artifact, id: artifact.manifest.id ?? artifact.id, version: artifact.manifest.version ?? artifact.version }. Top-level id and version are lifted from artifact.manifest, but engines (and anything else the handshake reads at the manifest top level) stays nested under manifest.manifest. The handshake (packages/metadata-core/src/protocol-handshake.ts:555) then finds no range and loads the package unchecked. A ^17 or ^19 artifact would therefore install without the OS_PROTOCOL_INCOMPATIBLE refusal that POST /packages gives (QA run #27392, item platform-core.manifest-install-contract). That consequence is inferred, NOT MEASURED.
Work
Measure first with the CLI binary: a ^17 (or ^19) artifact through os package install ./dist/objectstack.json. Expected today: it installs. Expected after: 422 OS_PROTOCOL_INCOMPATIBLE. Then fix whichever side owns the shape. Either the CLI lifts the manifest fields the handshake reads, or install-local reads a compiled artifact's nested manifest the way the catalog path does. Pick the one the measurement shows to be the intended contract. Add a test with a ^18 control.
Business reason
The ADR-0087 handshake is what stops an artifact built for another protocol from loading half-working. The air-gapped install path is the one an administrator uses without a catalog, and it skips the handshake today.
Reader
The triage seat grades and routes it (likely domain:cli, or domain:server if install-local owns the fix).
Dedupe
The 500 most recent issues and PRs (read 2026-11-01T05:10Z), titles grepped for engines\.protocol|protocol handshake|protocol range|assertProtocolCompat: 0 hits. Open-issue search "engines.protocol": 6 hits, none on the install-local artifact path (#28505 is the card it was found under; #27392 and #27438 are QA run records for POST /packages). Control install on the 500: 20 hits.
Claim: PM loop round 4 · card thread · 2026-11-01T06:44Z
Session: session_0186vfjHHMsRXC9EUT9hTFMo (the seat); the card thread is session_01FEkQ5mLNytcuq6kvRwXHMq
Account: os-project-manager (the seat's linked user; the card's assignee)
Branch: claude/project-thread-0kdxhp (the card thread's harness-pinned branch; it names no issue, so this claim is the identity record)
Worktree: the card thread's own container checkout
Domain: domain:server
Seat: domain:server#2
Ruling-ref: the maintainer, 2026-11-01T03:46Z: 「server 车道现在就是你负责,任务有一大堆啊,都可以派,包括 p3」, with 2026-10-26T10:29Z 「p1 p2 处理完了,就可以处理 p3」. Also the maintainer, 2026-11-01T06:40Z: 「任务很多啊 is:issue state:open label:pm:queue label:domain:server」. Triage 6554172575: "measure with the CLI binary first (a ^17 or ^19 artifact), then fix whichever side owns the shape." ⛔ No second handshake: a mismatched artifact gets the 422 OS_PROTOCOL_INCOMPATIBLE that POST /packages gives.
File surface: packages/cli/src/commands/package/install.ts and/or packages/cloud-connection/src/marketplace-install-local-plugin.ts (the artifact manifest read on install, not PR #28571's handleUninstall hunks), tests, and changesets.
Container & model: M, mode:thread, model: opus (--tier names no path mandate: PM's call, default), effort: high
Clause-②: no (narrowing — an incompatible artifact that installs today is refused; a contract review at CONTRACT_REVIEW_TIER is owed before the queue)
Metadata-protocol: none (expected; the dev measures and declares)
Responsibility: the code is the CLI's os package install artifact sender and the install-local door · the platform path is the ADR-0087 protocol handshake · reached by an administrator installing a built artifact file without a catalog
Thread-read: none
Premise: holds (read 2026-11-01T06:44Z at origin/main: install.ts lifts only id and version from artifact.manifest); the dev re-measures with the CLI binary first
Serial constraints cleared: PR #28571 merged; open PR #28554 touches marketplace-install-local-plugin.ts, and the dev re-reads it and does not edit its hunks
Resume-from: none — fresh from origin/main
State: → pm:dispatched, assigned to os-project-manager, recorded by this claim.
domain:server#2 · os-project-manager · session_01FEkQ5mLNytcuq6kvRwXHMq
os-dev-report
{
"issue": 28535,
"status": "done",
"branch": "claude/project-thread-0kdxhp",
"pr": "#28603",
"session": "session_01FEkQ5mLNytcuq6kvRwXHMq",
"premise_still_valid": true,
"summary": "Measured with the real CLI binary (packages/cli/bin/run.js) against a real os start: on origin/main a2e7556 a ^17 and a ^19 artifact install with exit 0 and the 'declares no engines.protocol range' WARN (^18 gets the same false WARN). The bare compiled artifact posted to install-local is already flattened and refused on base; only the CLI body escapes, because install.ts lifts id/version to the top and the door's normalizeBundle flattened only when the body had no top-level id/name. So the door owns the contract: normalizeBundle now flattens any body with a nested plain-object manifest through the existing flattenPackageBody (one flatten for inline, catalog and unmanaged import). The one assertProtocolCompat at step 1c is unchanged; the ADR-0141 dependency check (also nested before) now reads dependencies too. CLI untouched. After: ^17/^19 get 422 OS_PROTOCOL_INCOMPATIBLE through the binary (exit 1, nothing ledgered); ^18 installs with no WARN; no-engines installs with the one WARN.",
"tests": "head 8454de7. New cases in marketplace-install-local-protocol-handshake.test.ts (5) and marketplace-install-local-dependency-missing.test.ts (2), body built as install.ts builds it. Green: 28/28 for the two files; pnpm --filter @objectstack/cloud-connection test 63 files / 779 tests passed; typecheck and build exit 0. Red/ablation: plugin source swapped to a2e7556 (on-disk proof: flattenPackageBody(m) count 0, old guard count 1; restored via git checkout HEAD --, git diff HEAD 0 bytes, blob hash = HEAD): 4 failed / 24 passed, exactly ^17 refusal, byte-parity with flat manifest, ^18 no-WARN control, dependency refusal; bare-artifact and no-range controls green on both. Tests import the plugin by relative path (src), so no dist leg. Real binary before/after transcripts: project files pm-orders/server/evidence/28535/red.txt and green-bin.txt (script measure.mjs).",
"gates": "dispatch-gates --commands --repo objectstack-ai/objectstack derived 60 families on 8454de7; all 60 exit 0 (exit captured before any pipe); --ran: '60 derived famil(ies) accounted for — 60 run, 0 NOT-MEASURED'. check:dual-build-cjs-loads and check:type-check-debt first exited 3 (no full dist / lock queue-timeout behind my own dogfood run) and were re-run to exit 0 after the full packages build. eslint packages/cloud-connection --no-inline-config exit 0. CI check-runs on PR 28603: in_progress at report time, not re-run locally. Record: pm-orders/server/evidence/28535/gates-ran-8454de72.txt.",
"dogfood_battery": "8454de72 · os-verify-lock: VERDICT command-exit 0 (held 1866s) · Test Files 364 passed | 3 skipped (367) · Tests 2934 passed | 28 skipped (2962) · no failures",
"mcp_calls": "0",
"api_writes": "2 — fleet-write pr_create (POST pulls, PR 28603, no labels, no assignees; read-back 12002 bytes identical) and this os-dev-report comment (POST issues/28535/comments). Plus git push (not a REST write).",
"open_questions": [],
"out_of_scope_findings": [
"class: a · reach: kernel:ready rehydrate of a ledger entry any pre-fix os package install wrote — measured with a one-off probe in cloud-connection's harness: an entry in the CLI's lifted shape declaring engines.protocol ^17 (nested under manifest) is re-registered at boot with errors = 0 and no [protocol] line, because the rehydrate's checkProtocolCompat(entry.manifest) reads the stored entry unflattened (marketplace-install-local-plugin.ts, the kernel:ready rehydrate and the purge/reseed doors that judge entry.manifest) · evidence: PR 28603 Acceptance notes · dedupe words: rehydrate engines.protocol nested, ledger entry protocol check, install-local rehydrate handshake",
"carrier: none · noted, not filed — PR 28587 (#28534) also edits marketplace-install-local-plugin.ts (hunks near L650, L1018, L1947); no textual overlap with this PR's hunk near L1440, but a rebase order between the two is the seat's call"
]
}
Landed (Fixes): merged as 7449e479. POST /api/v1/marketplace/install-local reads a compiled artifact's nested manifest in the shape os package install ./dist/objectstack.json sends, so the one protocol handshake runs on it. An artifact whose engines.protocol excludes this runtime answers 422 OS_PROTOCOL_INCOMPATIBLE, unmet dependencies answer 422 DEPENDENCY_MISSING, and nothing is ledgered. A compatible artifact installs without the false "declares no engines.protocol range" WARN.
Unchanged: a flat manifest, the bare compiled artifact, an artifact with no engines (its one WARN), and the CLI.
Activity
objectstack-fleet commentedon Nov 1, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: 发布并装进一个环境 | none | P④
Triage: p2 ·
bug·domain:server·area:devpath·pm:queue· 2026-11-01T05:58Z⛔ Not a claim.
os package install ./dist/objectstack.jsonleavesenginesnested, so install-local loads the artifact without the ADR-0087 protocol check. The card scopes it to every artifact-file install, not only connector apps, so it goes to the lane rather than epic [Epic] Marketplace and connector auto-shelf — E1 platform prerequisites (openapi/mcp hardening, outbound OAuth, request signing), E2 administrator credential hand-off, E3 author recipes and handbook, E4 the first shelf of official connector apps #27293. p2.^17or^19artifact), then fix whichever side owns the shape.Generated by Claude Code
objectstack-fleet commentedon Nov 1, 2026
domain:server#2 · os-project-manager · session_0186vfjHHMsRXC9EUT9hTFMo
Claim: PM loop round 4 · card thread · 2026-11-01T06:44Z
Session:
session_0186vfjHHMsRXC9EUT9hTFMo(the seat); the card thread issession_01FEkQ5mLNytcuq6kvRwXHMqAccount:
os-project-manager(the seat's linked user; the card's assignee)Branch:
claude/project-thread-0kdxhp(the card thread's harness-pinned branch; it names no issue, so this claim is the identity record)Worktree: the card thread's own container checkout
Domain:
domain:serverSeat:
domain:server#2Ruling-ref: the maintainer, 2026-11-01T03:46Z: 「server 车道现在就是你负责,任务有一大堆啊,都可以派,包括 p3」, with 2026-10-26T10:29Z 「p1 p2 处理完了,就可以处理 p3」. Also the maintainer, 2026-11-01T06:40Z: 「任务很多啊 is:issue state:open label:pm:queue label:domain:server」. Triage
6554172575: "measure with the CLI binary first (a^17or^19artifact), then fix whichever side owns the shape." ⛔ No second handshake: a mismatched artifact gets the 422OS_PROTOCOL_INCOMPATIBLEthatPOST /packagesgives.File surface:
packages/cli/src/commands/package/install.tsand/orpackages/cloud-connection/src/marketplace-install-local-plugin.ts(the artifact manifest read on install, not PR #28571'shandleUninstallhunks), tests, and changesets.Container & model:
M,mode:thread,model: opus(--tiernames no path mandate: PM's call, default),effort: highClause-②: no (narrowing — an incompatible artifact that installs today is refused; a contract review at
CONTRACT_REVIEW_TIERis owed before the queue)Metadata-protocol: none (expected; the dev measures and declares)
Responsibility: the code is the CLI's
os package installartifact sender and the install-local door · the platform path is the ADR-0087 protocol handshake · reached by an administrator installing a built artifact file without a catalogThread-read: none
Premise: holds (read 2026-11-01T06:44Z at
origin/main:install.tslifts onlyidandversionfromartifact.manifest); the dev re-measures with the CLI binary firstSerial constraints cleared: PR #28571 merged; open PR #28554 touches
marketplace-install-local-plugin.ts, and the dev re-reads it and does not edit its hunksResume-from: none — fresh from
origin/mainState: →
pm:dispatched, assigned toos-project-manager, recorded by this claim.Generated by Claude Code
objectstack-fleet commentedon Nov 1, 2026
domain:server#2 · os-project-manager · session_01FEkQ5mLNytcuq6kvRwXHMq
os-dev-report
{
"issue": 28535,
"status": "done",
"branch": "claude/project-thread-0kdxhp",
"pr": "#28603",
"session": "session_01FEkQ5mLNytcuq6kvRwXHMq",
"premise_still_valid": true,
"summary": "Measured with the real CLI binary (packages/cli/bin/run.js) against a real os start: on origin/main a2e7556 a ^17 and a ^19 artifact install with exit 0 and the 'declares no engines.protocol range' WARN (^18 gets the same false WARN). The bare compiled artifact posted to install-local is already flattened and refused on base; only the CLI body escapes, because install.ts lifts id/version to the top and the door's normalizeBundle flattened only when the body had no top-level id/name. So the door owns the contract: normalizeBundle now flattens any body with a nested plain-object manifest through the existing flattenPackageBody (one flatten for inline, catalog and unmanaged import). The one assertProtocolCompat at step 1c is unchanged; the ADR-0141 dependency check (also nested before) now reads dependencies too. CLI untouched. After: ^17/^19 get 422 OS_PROTOCOL_INCOMPATIBLE through the binary (exit 1, nothing ledgered); ^18 installs with no WARN; no-engines installs with the one WARN.",
"tests": "head 8454de7. New cases in marketplace-install-local-protocol-handshake.test.ts (5) and marketplace-install-local-dependency-missing.test.ts (2), body built as install.ts builds it. Green: 28/28 for the two files; pnpm --filter @objectstack/cloud-connection test 63 files / 779 tests passed; typecheck and build exit 0. Red/ablation: plugin source swapped to a2e7556 (on-disk proof: flattenPackageBody(m) count 0, old guard count 1; restored via git checkout HEAD --, git diff HEAD 0 bytes, blob hash = HEAD): 4 failed / 24 passed, exactly ^17 refusal, byte-parity with flat manifest, ^18 no-WARN control, dependency refusal; bare-artifact and no-range controls green on both. Tests import the plugin by relative path (src), so no dist leg. Real binary before/after transcripts: project files pm-orders/server/evidence/28535/red.txt and green-bin.txt (script measure.mjs).",
"gates": "dispatch-gates --commands --repo objectstack-ai/objectstack derived 60 families on 8454de7; all 60 exit 0 (exit captured before any pipe); --ran: '60 derived famil(ies) accounted for — 60 run, 0 NOT-MEASURED'. check:dual-build-cjs-loads and check:type-check-debt first exited 3 (no full dist / lock queue-timeout behind my own dogfood run) and were re-run to exit 0 after the full packages build. eslint packages/cloud-connection --no-inline-config exit 0. CI check-runs on PR 28603: in_progress at report time, not re-run locally. Record: pm-orders/server/evidence/28535/gates-ran-8454de72.txt.",
"dogfood_battery": "8454de72 · os-verify-lock: VERDICT command-exit 0 (held 1866s) · Test Files 364 passed | 3 skipped (367) · Tests 2934 passed | 28 skipped (2962) · no failures",
"mcp_calls": "0",
"api_writes": "2 — fleet-write pr_create (POST pulls, PR 28603, no labels, no assignees; read-back 12002 bytes identical) and this os-dev-report comment (POST issues/28535/comments). Plus git push (not a REST write).",
"open_questions": [],
"out_of_scope_findings": [
"class: a · reach: kernel:ready rehydrate of a ledger entry any pre-fix os package install wrote — measured with a one-off probe in cloud-connection's harness: an entry in the CLI's lifted shape declaring engines.protocol ^17 (nested under manifest) is re-registered at boot with errors = 0 and no [protocol] line, because the rehydrate's checkProtocolCompat(entry.manifest) reads the stored entry unflattened (marketplace-install-local-plugin.ts, the kernel:ready rehydrate and the purge/reseed doors that judge entry.manifest) · evidence: PR 28603 Acceptance notes · dedupe words: rehydrate engines.protocol nested, ledger entry protocol check, install-local rehydrate handshake",
"carrier: none · noted, not filed — PR 28587 (#28534) also edits marketplace-install-local-plugin.ts (hunks near L650, L1018, L1947); no textual overlap with this PR's hunk near L1440, but a rebase order between the two is the seat's call"
]
}
Generated by Claude Code
objectstack-fleet commentedon Nov 1, 2026
domain:server#2 · os-project-manager · session_0186vfjHHMsRXC9EUT9hTFMo
Landing record · #28535 · PR #28603
domain:serverseat 2 ·session_0186vfjHHMsRXC9EUT9hTFMo· 2026-11-01T08:14Zgit ls-remote origin 'refs/heads/gh-readonly-queue/main/pr-28603-*'git merge-base --is-ancestor 7449e479 origin/maingit grep -c "isPlainObject(m) ? flattenPackageBody(m)" origin/main -- packages/cloud-connection/src/marketplace-install-local-plugin.ts7449e479.POST /api/v1/marketplace/install-localreads a compiled artifact's nested manifest in the shapeos package install ./dist/objectstack.jsonsends, so the one protocol handshake runs on it. An artifact whoseengines.protocolexcludes this runtime answers 422OS_PROTOCOL_INCOMPATIBLE, unmet dependencies answer 422DEPENDENCY_MISSING, and nothing is ledgered. A compatible artifact installs without the false "declares no engines.protocol range" WARN.Release: claim
6554580917(session_0186vfjHHMsRXC9EUT9hTFMo, branchclaude/project-thread-0kdxhp) · landed.pm:dispatchedremoved; assignee cleared; the card closed on merge.Generated by Claude Code