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/serve --no-server, the remainder of #23623: the objectstack:listening IPC message and the runtime state file still announce http://localhost:PORT with nothing listening, and a config-mounted server's banner names an unmounted MCP route #23743
Filing gate ①. This is the remainder of #23623: the address announcements PR #23741 left as they are, because the seat's dispatch fenced them out. Both are measured at the public door by #23623's dev, on base 9bb93706f and on PR #23741's head 30b5c246e (os-dev-report6204307328, out-of-scope findings 1 and 2, and open_questions 1).
Filed by domain:cli seat 1 (#6024) · os-bill · session session_01FLwgbTSmGMrqsXkBDsiwfG, in the same act as the seat's review of PR #23741. ⛔ Not a claim. Grade and lane are triage's.
1. The machine channels, class (b)
objectstack serve objectstack.config.ts --no-server --preset minimal (production, a host fixture, spawned with an ipc channel) received { type: 'objectstack:listening', port: 35809, url: 'http://localhost:35809' }. A GET to that port answered ECONNREFUSED. --dev --no-server did the same.
The contract it breaks:content/docs/deployment/cli.mdx:269: "objectstack:listening | os serve | The HTTP server is bound. Carries { port, url } — the port actually bound".
runtime.<environment>.<project>.json is written with the same port and url on every --no-server boot measured. No docs page states a contract for that file; serve.ts calls it a best-effort supervision file.
Reach: the message's only in-repo consumer is the os dev parent (dev.ts:707), and it never spawns a --no-server child (os dev declares no server flag). So no in-repo consumer is reached; an external supervisor that spawns os serve --no-server with an ipc channel is.
2. The banner's MCP: row under a config-mounted server, class (a)
objectstack serve objectstack.config.ts --no-server --preset minimal, with a config that mounts its own new HonoServerPlugin({ port }): the banner prints MCP: http://localhost:PORT/api/v1/mcp and its connect hint. GET /api/v1/mcp answers 404 (/api/v1/health404 too), while /api/v1/data/fx_task answers 401, so the transport listens.
Reach: the dev found no in-repo producer of the shape. The two docs pages that mount HonoServerPlugin build a kernel programmatically and do not run os serve.
Triage grades it and routes it. Both halves land in packages/cli/src/commands/serve.ts (domain:cli), after PR #23741.
Half 1: whether objectstack:listening and the state file are sent or written at all on a boot with no transport, or carry a field saying none is bound, is a consumer-contract question. The docs row is the contract.
MCP search_issues on objectstack-ai/objectstack, closed included: serve --no-server objectstack:listening IPC message runtime state file announces port url nothing listening gave 0 hits; objectstack:listening no-server gave 0; banner MCP row route not mounted dispatcher not composed 404 gave 2 (#9823 and #4886, both closed, neither this).
Half 1 breaks the documented objectstack:listening contract (content/docs/deployment/cli.mdx:269), but no in-repo consumer spawns --no-server with an ipc channel. Half 2 needs a config shape with no in-repo producer.
Not the protocol-first class: it pulls service behaviour back to a declared contract, and no door's accept set moves.
Claim: PM loop round 1, the third slot of the maintainer's temporary concurrency (「临时并发可以加到3」; for this slot 「换一个卡派」, in place of #23863, which waits on PR #23862). Label order: the open pm:queue bugs left in domain:cli are p3; this is the oldest. #23743: on a --no-server boot, objectstack:listening and the runtime state file stop announcing an HTTP address nothing listens on, and the banner's MCP: row prints only when the route's owner is composed · 2026-10-16T10:37Z
Session: session_01PFB9ZGRWYvjhTXsd8i6KBp
Account: marchtian (the seat's linked user as GET /user answers it; always the card's assignee)
Branch: claude/issue-23743-no-server-announcements
Worktree: objectstack-issue-23743
Domain: domain:cli
Seat: domain:cli#1 (seat post #6024)
File surface (read on origin/main6422da58e8; line numbers move; stop on a breach and explain it in the report):
packages/cli/src/commands/serve.ts: publishBoundPort and its three channels (about :763-:870), the state-file write it drives, and the banner's MCP: gate beside readComposedHttpServer (about :531-:566).
packages/cli/src/utils/format.ts: the banner's MCP: row only, if the gate lands there.
content/docs/deployment/cli.mdx: the objectstack:listening / objectstack:seed-settled rows (:269-:270) only if the behaviour they state changes.
Their pins (new test files beside them under packages/cli/src/**), and one .changeset/23743-*.md.
os-dev-report
{
"issue": 23743,
"status": "done",
"branch": "claude/issue-23743-no-server-announcements",
"pr": "#23947",
"session": "session_01PFB9ZGRWYvjhTXsd8i6KBp — the PM session's id, which this subagent shares (Claude-Session line on every commit); identity is the branch named in claim 6213641477",
"premise_still_valid": true,
"summary": "Both halves reproduced at the door on base 7a6ba03 before any edit. Half 1: production --no-server --preset minimal (ipc channel) received {type:'objectstack:listening', port:38393, url:'http://localhost:38393'} and found runtime.env_local.PROJECT.json with that url, and every probe answered ECONNREFUSED; --dev --no-server did the same. Half 2: a config-mounted HonoServerPlugin under --no-server printed MCP: plus its connect hint, while /api/v1/mcp answered 404 and /api/v1/data/fx_task answered 401. Fix, all in packages/cli/src/commands/serve.ts: the publish site runs publishBoundPort(...) only when httpServer === 'composed' and otherwise prints the banner alone. httpServer is the same resolveHttpServerComposition value the banner's address rows read, so one predicate decides all three channels. objectstack:seed-settled is still sent on such a boot and is its only message. The state file is not written on such a boot; its payload shape is unchanged. The banner's MCP: row now gets isMcpServerEnabled() && mcpRouteMounted, where mcpRouteMounted = httpServer === 'composed' && readComposedMcpRouteOwner(kernel), a new kernel read: kernel.hasPlugin('com.objectstack.runtime.dispatcher'), the plugin that mounts /api/v1/mcp. Both docs rows (cli.mdx :269-:270) were updated together. Zone 2 measured: (1) holds as stated. (2) The seed-settled consumers are the os dev relay (dev.ts:769, never spawns --no-server) and the docs example, which waits for seed-settled alone; SeedSettledMessage's no-hang rule decides that it is still sent, alone. (3) The state-file readers in this repo are scripts/publish-smoke.sh (spawns objectstack dev, reads .port, curls health) and CLI tests only; no docs contract exists; choice: not written. (4) No live route table exists on IHttpServer; the narrowest sound read is the kernel's plugin registry, which HonoServerPlugin already uses for the dispatcher name. Draft PR #23947 is open with assignee marchtian; CI is in_progress.",
"tests": "New unit file src/commands/serve-no-transport-announcements.test.ts (10 cases): readComposedMcpRouteOwner against a real ObjectKernel (createDispatcherPlugin registered gives true; transport-only gives false); MCP_ROUTE_OWNER_PLUGIN read off createDispatcherPlugin().name; it asks for that name only; false when the kernel cannot answer; run() wiring source pins with comments masked. New integration file src/commands/serve-no-transport-announcements.integration.test.ts: 3 boots of bin/run.js with an ipc channel and a watched OS_HOME. (1) Production --no-server: no listening message, messages exactly ['objectstack:seed-settled'], no runtime.*.json ever created (expect.soft, 3 legs). (2) Control default boot: [listening, seed-settled], the message equals the API: row's {port,url}, the state file carries the same, MCP: row, health 200, /mcp not 404. (3) Hono --no-server: no MCP: row or hint, /mcp 404, IPC and state file carry the API: address. test-budget 30 from local runs of 19.4 / 18.9 / 20.9 s. Unit tier as 4 shards, pnpm --filter @objectstack/cli exec vitest run --project unit --maxWorkers=2 --shard=K/4, on 23b3033. Shard 1: 76 files, 1418 passed. Shard 2: 1099 passed, 3 failed, all 'Test timed out in 5000ms' while my own unlocked gate battery shared the cores; the 2 files re-run alone gave 'Test Files 2 passed (2) · Tests 41 passed (41)'. Shard 3: 918 passed. Shard 4: 1071 passed, 1 failed, a real one: serve-observability-registration.test.ts locates the transport by the first raw-source 'new HonoServerPlugin(' and my docblock spelled it; fixed in cccb00e. On final head cccb00e after rebuilding the CLI: 6 touched unit files 'Test Files 6 passed (6) · Tests 82 passed (82)'; integration, scoped (new file, serve-no-server-banner, test/serve-no-storage-boot-guard, test/dev-boot-output-order) 'Test Files 4 passed (4) · Tests 15 passed (15)'; OS_TEST_TIERS=nightly test/serve-publishes-bound-port.e2e.test.ts 'Tests 6 passed (6)'; the rest of the integration tier is declared to CI. Ablation (fix committed first; ablation-replace.mjs wrap mode plus a trap restoring from HEAD; CLI rebuilt; ablation-dist-preflight). Gate leg: anchor x1 to x0, blob 8de5619d0a58 to f04d083f4255, marker in 1 built file. Result 'Tests 3 failed | 10 passed (13)': all three no-transport soft legs red (listening sent, not the only message, state file written), both wiring pins red, both controls green; direction: turned red, as predicted. Restore: blob == HEAD, git diff HEAD empty, status clean, --absent in 640 files, 13 passed. MCP leg: blob 8de5619d0a58 to 630307660e27, marker in 1 built file. Result 'Tests 2 failed | 11 passed (13)' (Hono case 'an MCP: row printed for an unmounted route' and the mcpEnabled source pin); direction: turned red. Restore proven the same way, 13 passed. Door probes before (7a6ba03) and after (cccb00e) in the PR's table, plus an after-only control: config-mounted Hono with --server prints MCP: and /mcp answers 401.",
"gates": "On final head cccb00e: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no paths). Its stderr reads: tree objectstack-ai/objectstack at cccb00e, 6 paths vs merge base 944f038. It derived 96 commands; each was run as cmd > log 2>&1; ec=$?, and 96 exited 0. On the first pass (23b3033) spec check:skill-examples, check:dual-build-cjs-loads and check:i18n-coverage exited 3 (PREREQUISITE NOT MET: no dist for studio, client-react, connector-slack, example apps …); after turbo run build of those (75 tasks, exit 0) all three exit 0. --ran ran.list prints '✓ dispatch-gates --ran: 96 derived famil(ies) accounted for — 96 run, 0 NOT-MEASURED (a DERIVED zero — all 96 recorded an exit code and none of them is 3)'. pnpm --filter @objectstack/cli typecheck exits 0 ('check:test-typecheck: OK'); tsc -p tsconfig.json --noEmit --listFilesOnly lists both new files. Lint lane: pnpm exec eslint --no-inline-config over the 4 changed .ts files exits 0, no output. Not local by rule: check:dev-prereqs, check:skill-frame-freshness, check-platform-checklist --changed-from (no export renamed or removed). PR #23947 check-runs read once at open (head cccb00e): 24 runs. 'No other open PR may claim the same issue' success; 'Packed-tarball smoke (opt-in)' skipped; 'Lint · ESLint' queued; the other 21 in_progress (Check Changeset, Lint · repo & tooling gates, Lint · PM dispatch-gates, Type Check · workspace, Governed Surface Queue Guard, The card this PR closes must claim this branch, …). NOT MEASURED: CI convergence is the PM's.",
"mcp_calls": "0",
"api_writes": "3 REST writes via the fleet-write relay as objectstack-fleet[bot]: POST /repos/objectstack-ai/objectstack/pulls (draft, #23947) and POST /repos//issues/23947/assignees (marchtian), both legs of one pr_create action (run 38908441252; body read back byte-identical, 16271 bytes); POST /repos//issues/23743/comments (this os-dev-report). git push x7 (the empty-branch probe and 6 pushes of commits, including one merge of origin/main) is not REST. No label write, no PR-body PATCH.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: #23744 · production --no-server --preset minimal prints its banner about 5.1-5.8 s after spawn and then exits 0 by itself within milliseconds, on base 7a6ba03 and on cccb00e; seed-settled arrives before that exit in every run measured; --dev --no-server stays up · noted, not filed (that card's own question)",
"noted, not filed (Acceptance notes; no class): a stale runtime state file left by a hard-killed earlier boot of the same project is no longer overwritten by a no-transport boot; the start.ts comment saying serve publishes objectstack:listening 'unconditionally' is now conditional (os start never passes --no-server); a config-mounted dispatcher with a non-default prefix still gets an MCP: row naming /api/v1/mcp (no in-repo producer; unchanged by this PR)"
],
"line_budget": "n/a",
"deviations": [
"packages/cli/src/utils/format.ts: the gate landed in serve.ts, not format.ts. format.ts got a doc-comment-only edit (4+/3-) on the mcpEnabled field the MCP: row reads, so it states what serve now passes. printServerReady is untouched.",
"Merged origin/main into the branch before opening the PR (23b3033, a clean merge; upstream touched packages/cli dev.ts and storage-driver.ts, not serve.ts or format.ts), per AGENTS.md multi-agent §10. The CLI closure was rebuilt and packages/runtime/.objectstack removed.",
"The unit tier was run as 4 shards on 23b3033, not on the final head. cccb00e changes only a docblock in serve.ts, and the failing file plus the 5 serve/banner unit files were re-run on cccb00e. Shard 2's 3 failures were 5000 ms timeouts while my own unlocked gate battery shared the cores; its two files passed alone.",
"Two lock calls returned 99 (queue-timeout; NOT MEASURED, re-run later). One lock call outlived the Bash foreground timeout and the harness moved it to the background. I read its logs and waited on its recorded holder PID with tail --pid; nothing was re-run.",
"Both ablations ran against serve.ts blob 8de5619d0a58 (99c982b to 23b3033), before the cccb00e docblock rewording; they were not re-run on the final head.",
"Label writes: zero. The dispatch named no label, and skip-changeset does not apply (the diff publishes @objectstack/cli, changeset included).",
"The harness attribution reminder asked for a model-named Co-Authored-By trailer and a different PR footer. Per AGENTS.md and the dispatch, commits carry the model-free pair (Claude-Session plus Co-authored-by: Claude) and the PR body ends with the session-URL footer.",
"Ran test/serve-publishes-bound-port.e2e.test.ts locally under OS_TEST_TIERS=nightly. It is the publication's own end-to-end pin; CI runs it nightly, not on the PR."
],
"files_changed": [
"A .changeset/23743-no-server-announcements.md (+12)",
"M content/docs/deployment/cli.mdx (+2 / -2)",
"A packages/cli/src/commands/serve-no-transport-announcements.integration.test.ts (+387)",
"A packages/cli/src/commands/serve-no-transport-announcements.test.ts (+143)",
"M packages/cli/src/commands/serve.ts (+107 / -7)",
"M packages/cli/src/utils/format.ts (+4 / -3)",
"6 files, +655 / -12, vs merge base 944f038"
],
"cleanup": "Every process I started was confirmed gone by recorded PID: 9 probe boots, 2 gate-battery runners and the 4 backgrounded lock calls; every foreground lock call returned its VERDICT line. The worktree's node_modules are removed and the worktree is deleted after this comment is posted (branch fully pushed at cccb00e)."
}
161aee1047 is an ancestor (fetched in this act); single parent (squash)
Queue branch
gh-readonly-queue/main/pr-23947-*: 0 refs left
Landed content
MCP_ROUTE_OWNER_PLUGIN: 2 hits and httpServer === 'composed': 2 hits in packages/cli/src/commands/serve.ts on origin/main
State:#23743 closed completed by Fixes #23743, the PR body's only closing keyword; pm:dispatched stripped in this act (domain:cli, priority:p3, bug stay). This seat's hold on serve.ts's publish site is released. Carried: the report's process-lifetime measurement goes to #23744 in the same act.
Activity
objectstack-fleet commentedon Oct 16, 2026
First grade ·
domain:cli· p3 ·pm:queue· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-16T01:00ZRead in this act: the body in full, 0 comments.
domain:cli. Both halves land inpackages/cli/src/commands/serve.ts.objectstack:listeningcontract (content/docs/deployment/cli.mdx:269), but no in-repo consumer spawns--no-serverwith anipcchannel. Half 2 needs a config shape with no in-repo producer.pm:queue. PR fix(cli): the ready banner prints API: and MCP: addresses only when an HTTP server is composed #23741 merged at 2026-10-15T23:57Z, which is the order the body names.finding→bug.⛔ Not a claim.
objectstack-fleet commentedon Oct 16, 2026
Claim: PM loop round 1, the third slot of the maintainer's temporary concurrency (「临时并发可以加到3」; for this slot 「换一个卡派」, in place of #23863, which waits on PR #23862). Label order: the open
pm:queuebugs left indomain:cliare p3; this is the oldest. #23743: on a--no-serverboot,objectstack:listeningand the runtime state file stop announcing an HTTP address nothing listens on, and the banner'sMCP:row prints only when the route's owner is composed · 2026-10-16T10:37ZSession:
session_01PFB9ZGRWYvjhTXsd8i6KBpAccount:
marchtian(the seat's linked user asGET /useranswers it; always the card's assignee)Branch:
claude/issue-23743-no-server-announcementsWorktree:
objectstack-issue-23743Domain:
domain:cliSeat:
domain:cli#1(seat post #6024)File surface (read on
origin/main6422da58e8; line numbers move; stop on a breach and explain it in the report):packages/cli/src/commands/serve.ts:publishBoundPortand its three channels (about:763-:870), the state-file write it drives, and the banner'sMCP:gate besidereadComposedHttpServer(about:531-:566).packages/cli/src/utils/format.ts: the banner'sMCP:row only, if the gate lands there.content/docs/deployment/cli.mdx: theobjectstack:listening/objectstack:seed-settledrows (:269-:270) only if the behaviour they state changes.packages/cli/src/**), and one.changeset/23743-*.md.--no-server --preset minimalprocess lifetime (cli/serve:--no-server --preset minimalprints the ready banner ending "Press Ctrl+C to stop" and then exits 0 on its own about 40 ms later, removing the runtime state file it had just written #23744, next on this file in this seat's serial queue);packages/cli/src/commands/dev.ts(cli: thepnpm devwatcher prints only "✗ compile failed (Nms)" when a save is refused — the refusal goes to compile's stdout, which the watcher discards #23820, seat 2; itsobjectstack:listeningconsumer about:769is read, not edited);packages/runtime.Container & model:
M(three announcement channels and one banner row on a kernel-only boot, measured at the door),mode:subagent,model: TIER_DEFAULT(dispatch-gates --tier: no path-derived mandate)Clause-②: no
Basis for the Clause-② line: it pulls the IPC message back to its documented contract.
content/docs/deployment/cli.mdx:269: "objectstack:listening|os serve| The HTTP server is bound. Carries{ port, url }— the port actually bound". A message announcing an address with nothing bound is outside that text. The state file has no documented contract (serve.tscalls it best-effort supervision), and the banner is human text.serve.tsis not reachable from@objectstack/cli'sexportsbeyond theServeCommanddefault. Nopackages/specedit.Responsibility:
packages/cli'sos serve, platform code in this lane | none: PR fix(cli): the ready banner prints API: and MCP: addresses only when an HTTP server is composed #23741 made only the banner'sAPI:row read whether a transport is composed | an external supervisor that spawnsos serve --no-serverwith anipcchannel and trustsobjectstack:listening; no in-repo consumer is reached (os devnever spawns--no-server); half 2 needs a config that mounts its ownHonoServerPlugin, with no in-repo producer (both measured by cli/serve: with --no-server the ready banner still prints "API: http://localhost:PORT/" and an MCP connect URL, though no HTTP server is composed and nothing listens #23623's dev, report6204307328)Thread-read: 6205610412
Serial constraints cleared:
pm:dispatchedclaim namesserve.ts,format.tsorpackages/cli/src/**(all 25 newest claims read in this act). No open PR editsserve.ts: its last change onmainis PR fix(cli): the ready banner prints API: and MCP: addresses only when an HTTP server is composed #23741 (2906cd8d2e).--no-server --preset minimalprints the ready banner ending "Press Ctrl+C to stop" and then exits 0 on its own about 40 ms later, removing the runtime state file it had just written #23744 (p3, same file) is not folded: its claimant first establishes whether a kernel-only boot stays up or exits, and the fix differs by answer (fold gate ① fails). It runs after this card lands.Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
os-dev-report
{
"issue": 23743,
"status": "done",
"branch": "claude/issue-23743-no-server-announcements",
"pr": "#23947",
"session": "session_01PFB9ZGRWYvjhTXsd8i6KBp — the PM session's id, which this subagent shares (Claude-Session line on every commit); identity is the branch named in claim 6213641477",
"premise_still_valid": true,
"summary": "Both halves reproduced at the door on base 7a6ba03 before any edit. Half 1: production
--no-server --preset minimal(ipc channel) received {type:'objectstack:listening', port:38393, url:'http://localhost:38393'} and found runtime.env_local.PROJECT.json with that url, and every probe answered ECONNREFUSED;--dev --no-serverdid the same. Half 2: a config-mounted HonoServerPlugin under--no-serverprinted MCP: plus its connect hint, while /api/v1/mcp answered 404 and /api/v1/data/fx_task answered 401. Fix, all in packages/cli/src/commands/serve.ts: the publish site runs publishBoundPort(...) only when httpServer === 'composed' and otherwise prints the banner alone. httpServer is the same resolveHttpServerComposition value the banner's address rows read, so one predicate decides all three channels. objectstack:seed-settled is still sent on such a boot and is its only message. The state file is not written on such a boot; its payload shape is unchanged. The banner's MCP: row now gets isMcpServerEnabled() && mcpRouteMounted, where mcpRouteMounted = httpServer === 'composed' && readComposedMcpRouteOwner(kernel), a new kernel read: kernel.hasPlugin('com.objectstack.runtime.dispatcher'), the plugin that mounts /api/v1/mcp. Both docs rows (cli.mdx :269-:270) were updated together. Zone 2 measured: (1) holds as stated. (2) The seed-settled consumers are the os dev relay (dev.ts:769, never spawns --no-server) and the docs example, which waits for seed-settled alone; SeedSettledMessage's no-hang rule decides that it is still sent, alone. (3) The state-file readers in this repo are scripts/publish-smoke.sh (spawnsobjectstack dev, reads .port, curls health) and CLI tests only; no docs contract exists; choice: not written. (4) No live route table exists on IHttpServer; the narrowest sound read is the kernel's plugin registry, which HonoServerPlugin already uses for the dispatcher name. Draft PR #23947 is open with assignee marchtian; CI is in_progress.","tests": "New unit file src/commands/serve-no-transport-announcements.test.ts (10 cases): readComposedMcpRouteOwner against a real ObjectKernel (createDispatcherPlugin registered gives true; transport-only gives false); MCP_ROUTE_OWNER_PLUGIN read off createDispatcherPlugin().name; it asks for that name only; false when the kernel cannot answer; run() wiring source pins with comments masked. New integration file src/commands/serve-no-transport-announcements.integration.test.ts: 3 boots of bin/run.js with an ipc channel and a watched OS_HOME. (1) Production --no-server: no listening message, messages exactly ['objectstack:seed-settled'], no runtime.*.json ever created (expect.soft, 3 legs). (2) Control default boot: [listening, seed-settled], the message equals the API: row's {port,url}, the state file carries the same, MCP: row, health 200, /mcp not 404. (3) Hono --no-server: no MCP: row or hint, /mcp 404, IPC and state file carry the API: address. test-budget 30 from local runs of 19.4 / 18.9 / 20.9 s. Unit tier as 4 shards,
pnpm --filter @objectstack/cli exec vitest run --project unit --maxWorkers=2 --shard=K/4, on 23b3033. Shard 1: 76 files, 1418 passed. Shard 2: 1099 passed, 3 failed, all 'Test timed out in 5000ms' while my own unlocked gate battery shared the cores; the 2 files re-run alone gave 'Test Files 2 passed (2) · Tests 41 passed (41)'. Shard 3: 918 passed. Shard 4: 1071 passed, 1 failed, a real one: serve-observability-registration.test.ts locates the transport by the first raw-source 'new HonoServerPlugin(' and my docblock spelled it; fixed in cccb00e. On final head cccb00e after rebuilding the CLI: 6 touched unit files 'Test Files 6 passed (6) · Tests 82 passed (82)'; integration, scoped (new file, serve-no-server-banner, test/serve-no-storage-boot-guard, test/dev-boot-output-order) 'Test Files 4 passed (4) · Tests 15 passed (15)'; OS_TEST_TIERS=nightly test/serve-publishes-bound-port.e2e.test.ts 'Tests 6 passed (6)'; the rest of the integration tier is declared to CI. Ablation (fix committed first; ablation-replace.mjs wrap mode plus a trap restoring from HEAD; CLI rebuilt; ablation-dist-preflight). Gate leg: anchor x1 to x0, blob 8de5619d0a58 to f04d083f4255, marker in 1 built file. Result 'Tests 3 failed | 10 passed (13)': all three no-transport soft legs red (listening sent, not the only message, state file written), both wiring pins red, both controls green; direction: turned red, as predicted. Restore: blob == HEAD, git diff HEAD empty, status clean, --absent in 640 files, 13 passed. MCP leg: blob 8de5619d0a58 to 630307660e27, marker in 1 built file. Result 'Tests 2 failed | 11 passed (13)' (Hono case 'an MCP: row printed for an unmounted route' and the mcpEnabled source pin); direction: turned red. Restore proven the same way, 13 passed. Door probes before (7a6ba03) and after (cccb00e) in the PR's table, plus an after-only control: config-mounted Hono with --server prints MCP: and /mcp answers 401.","gates": "On final head cccb00e:
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack(no paths). Its stderr reads: tree objectstack-ai/objectstack at cccb00e, 6 paths vs merge base 944f038. It derived 96 commands; each was run ascmd > log 2>&1; ec=$?, and 96 exited 0. On the first pass (23b3033) spec check:skill-examples, check:dual-build-cjs-loads and check:i18n-coverage exited 3 (PREREQUISITE NOT MET: no dist for studio, client-react, connector-slack, example apps …); afterturbo run buildof those (75 tasks, exit 0) all three exit 0.--ran ran.listprints '✓ dispatch-gates --ran: 96 derived famil(ies) accounted for — 96 run, 0 NOT-MEASURED (a DERIVED zero — all 96 recorded an exit code and none of them is 3)'.pnpm --filter @objectstack/cli typecheckexits 0 ('check:test-typecheck: OK');tsc -p tsconfig.json --noEmit --listFilesOnlylists both new files. Lint lane:pnpm exec eslint --no-inline-configover the 4 changed .ts files exits 0, no output. Not local by rule: check:dev-prereqs, check:skill-frame-freshness, check-platform-checklist --changed-from (no export renamed or removed). PR #23947 check-runs read once at open (head cccb00e): 24 runs. 'No other open PR may claim the same issue' success; 'Packed-tarball smoke (opt-in)' skipped; 'Lint · ESLint' queued; the other 21 in_progress (Check Changeset, Lint · repo & tooling gates, Lint · PM dispatch-gates, Type Check · workspace, Governed Surface Queue Guard, The card this PR closes must claim this branch, …). NOT MEASURED: CI convergence is the PM's.","mcp_calls": "0",
"api_writes": "3 REST writes via the fleet-write relay as objectstack-fleet[bot]: POST /repos/objectstack-ai/objectstack/pulls (draft, #23947) and POST /repos//issues/23947/assignees (marchtian), both legs of one pr_create action (run 38908441252; body read back byte-identical, 16271 bytes); POST /repos//issues/23743/comments (this os-dev-report). git push x7 (the empty-branch probe and 6 pushes of commits, including one merge of origin/main) is not REST. No label write, no PR-body PATCH.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: #23744 · production
--no-server --preset minimalprints its banner about 5.1-5.8 s after spawn and then exits 0 by itself within milliseconds, on base 7a6ba03 and on cccb00e; seed-settled arrives before that exit in every run measured;--dev --no-serverstays up · noted, not filed (that card's own question)","noted, not filed (Acceptance notes; no class): a stale runtime state file left by a hard-killed earlier boot of the same project is no longer overwritten by a no-transport boot; the start.ts comment saying serve publishes objectstack:listening 'unconditionally' is now conditional (os start never passes --no-server); a config-mounted dispatcher with a non-default prefix still gets an MCP: row naming /api/v1/mcp (no in-repo producer; unchanged by this PR)"
],
"line_budget": "n/a",
"deviations": [
"packages/cli/src/utils/format.ts: the gate landed in serve.ts, not format.ts. format.ts got a doc-comment-only edit (4+/3-) on the mcpEnabled field the MCP: row reads, so it states what serve now passes. printServerReady is untouched.",
"Merged origin/main into the branch before opening the PR (23b3033, a clean merge; upstream touched packages/cli dev.ts and storage-driver.ts, not serve.ts or format.ts), per AGENTS.md multi-agent §10. The CLI closure was rebuilt and packages/runtime/.objectstack removed.",
"The unit tier was run as 4 shards on 23b3033, not on the final head. cccb00e changes only a docblock in serve.ts, and the failing file plus the 5 serve/banner unit files were re-run on cccb00e. Shard 2's 3 failures were 5000 ms timeouts while my own unlocked gate battery shared the cores; its two files passed alone.",
"Two lock calls returned 99 (queue-timeout; NOT MEASURED, re-run later). One lock call outlived the Bash foreground timeout and the harness moved it to the background. I read its logs and waited on its recorded holder PID with tail --pid; nothing was re-run.",
"Both ablations ran against serve.ts blob 8de5619d0a58 (99c982b to 23b3033), before the cccb00e docblock rewording; they were not re-run on the final head.",
"Label writes: zero. The dispatch named no label, and skip-changeset does not apply (the diff publishes @objectstack/cli, changeset included).",
"The harness attribution reminder asked for a model-named Co-Authored-By trailer and a different PR footer. Per AGENTS.md and the dispatch, commits carry the model-free pair (Claude-Session plus Co-authored-by: Claude) and the PR body ends with the session-URL footer.",
"Ran test/serve-publishes-bound-port.e2e.test.ts locally under OS_TEST_TIERS=nightly. It is the publication's own end-to-end pin; CI runs it nightly, not on the PR."
],
"files_changed": [
"A .changeset/23743-no-server-announcements.md (+12)",
"M content/docs/deployment/cli.mdx (+2 / -2)",
"A packages/cli/src/commands/serve-no-transport-announcements.integration.test.ts (+387)",
"A packages/cli/src/commands/serve-no-transport-announcements.test.ts (+143)",
"M packages/cli/src/commands/serve.ts (+107 / -7)",
"M packages/cli/src/utils/format.ts (+4 / -3)",
"6 files, +655 / -12, vs merge base 944f038"
],
"cleanup": "Every process I started was confirmed gone by recorded PID: 9 probe boots, 2 gate-battery runners and the 4 backgrounded lock calls; every foreground lock call returned its VERDICT line. The worktree's node_modules are removed and the worktree is deleted after this comment is posted (branch fully pushed at cccb00e)."
}
Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
ACCEPT → PR #23947 comment 6217016447 ·
domain:cliseat 1 ·marchtian· 2026-10-16T13:53Z. Carried to #23744 at landing: the report's process-lifetime measurement. Landing follows on this true-green head.Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
Landed: PR #23947 merged through the queue as
161aee1047·domain:cliseat 1 ·marchtian· sessionsession_01PFB9ZGRWYvjhTXsd8i6KBp· 2026-10-16T14:21Z.merged: true,merged_at2026-10-16T14:17:48Z; timelineadded_to_merge_queue2026-10-16T13:56:52Zorigin/main161aee1047is an ancestor (fetched in this act); single parent (squash)gh-readonly-queue/main/pr-23947-*: 0 refs leftMCP_ROUTE_OWNER_PLUGIN: 2 hits andhttpServer === 'composed': 2 hits inpackages/cli/src/commands/serve.tsonorigin/mainState: #23743 closed
completedbyFixes #23743, the PR body's only closing keyword;pm:dispatchedstripped in this act (domain:cli,priority:p3,bugstay). This seat's hold onserve.ts's publish site is released. Carried: the report's process-lifetime measurement goes to #23744 in the same act.Generated by Claude Code