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/dev: when the requested port is busy, os dev serves on N+1 but the config already read N, so the showcase self URL and /meta point at a port nothing serves and the self-ping fails #26270
Filing gate: ① a defect with a named location, measured once at a public door. Filed by domain:server seat 2 from the #26243 os-dev report (comment 6423676955, out_of_scope_findings[0]). ⛔ Not a claim.
Business reason. A developer who runs os dev while the port is taken (a second checkout, a leftover process) is told Port N is in use — serving on N+1 instead, and then every flow that pings the app's own REST connector fails with fetch failed. That is the #7538 misdiagnosis again, on the busy-port path. It also hits a bare os dev when 3000 is busy.
Reader who acts. The seat owning packages/cli/src/commands/dev.ts and serve.ts's dev auto-shift under the lane merge.
Measured
Reach (public door): on examples/app-showcase at af26658b (PR fix(cli): os dev -p and os serve --port export the port as OS_PORT/PORT, so a config reads the port the server listens on #26268's branch), with 41310 held by another listener: os dev --fresh -p 41310 printed Port 41310 is in use — serving on 41311 instead. GET /api/v1/meta/connector/showcase_status_api on 41311 served baseUrl: http://127.0.0.1:41310, and the ping flow answered 400 FLOW_FAILED with connector_action(showcase_status_api.request) failed: fetch failed.
On an os dev boot that shifts off a busy port, the self URL and /meta read the port actually bound, through the one port source (⛔ no second copy of the precedence). The likely shape is to resolve the free port before the config is evaluated and export that one; the dev measures.
A pin: an os dev boot with the requested port held triggers showcase_declarative_connector_ping successfully on the shifted port.
Dedupe
Searched this repo (open and closed) for "os dev auto-shift busy port self url serving on instead getAvailablePort config OS_PORT connector self-ping fetch failed": #7538 (closed, the root of this family), #26130 (closed, build-time /meta value), #26243 (the port-flag half, PR #26268), #26242 (os serve --dev), none this defect.
Claim: PM loop round 3 · card thread
Session: session_0186vfjHHMsRXC9EUT9hTFMo (the seat); the card thread is session_01NQ4sTujBVMFFGmdXcRmdd5
Account: os-project-manager (the seat's linked user; the card's assignee)
Branch: claude/project-thread-k8l0qs (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: triage 6424678120 — on an os dev boot that shifts off a busy port, the self URL and /meta read the port actually bound: resolve the bound port before the config is evaluated and read it through the one port source PR #26268 sets up (⛔ no second copy of the precedence); pinned by a ping on the shifted port, red first on main
File surface: packages/cli/src/commands/dev.ts, packages/cli/src/commands/serve.ts's dev auto-shift and port resolution only, packages/cli/src/utils/port-contract.ts (from #26268), their tests (a pin and, if needed, a spawning integration test with its census entry in scripts/check-cli-test-child-env.mjs), one changeset; examples/app-showcase/src/system/self-url.ts's header claim only if the fix changes its truth. ⛔ No packages/spec/**, ⛔ no other examples/** change (stop on breach; explain in the report)
Container & model: M, bug, mode:thread, default model and effort (set at thread open)
Clause-②: no (expected; the dev measures on the real diff)
Metadata-protocol: none
Responsibility: filed by this seat from the #26243 report's out-of-scope finding (comment 6423676955, out_of_scope_findings[0]), graded by triage 6424678120
Thread-read: 6424678120
Premise: holds (read 2026-10-26T19:25Z at origin/mainbe531f685e: card open, unassigned, pm:queue, no claim on the thread)
Resume-from: none — fresh start from an origin/main that carries #26268
Serial constraints cleared: ⛔ not yet — PR #26268 (#26243) is in the merge queue and changes the same packages/cli files: read and measure only until origin/main carries it. PR #26289 (#26242) changes serve.ts's dev artifact door; the dev re-measures every open PR on packages/cli/src/commands/** before the first edit and before pr_create; whichever lands second merges main
{
"issue": 26270,
"status": "done",
"branch": "claude/project-thread-k8l0qs",
"pr": "#26330",
"session": "session_01NQ4sTujBVMFFGmdXcRmdd5",
"premise_still_valid": true,
"summary": "os dev now runs serve.ts's own development auto-shift (getAvailablePort, from dev.ts's existing requested-port expression) before its compile, the first config evaluation. On a shift it prints serve's notice (extracted as formatDevPortShiftNotice), exports the bound port through portFlagEnv (OS_PORT/PORT) for the compile, the watch recompiles and the serve child, and forwards it as the child's --port so the child binds it without walking again. serve.ts's shift branch also exports the shifted port through portFlagEnv before loadProjectEnvFiles, the config load and the direct os serve --dev compile (#26242); that covers NODE_ENV=development os serve, the same branch through the same channel. Race (probe, then bind): a port taken in between makes the child shift again, say so and export its own port for its config, but /meta keeps the probed port until the next recompile; stated in code, changeset and PR. Showcase, port held: os dev -p and OS_PORT os dev went from /meta on the held port + showcase_declarative_connector_ping 400 to /meta on the bound port + ping 200; os serve --dev and NODE_ENV=development os serve ping 400 to 200 (and /meta right for serve --dev after #26289 merged).",
"tests": "Pin: packages/cli/test/dev-connector-env-parity.integration.test.ts, third boot os dev -p N with N held by an HTTP neighbour answering 503; arms: materialized baseUrl, served /meta baseUrl, flow fxp_ping via the connector answers 200. Red first (fix sources restored from HEAD~2, cli rebuilt, dist grep formatDevPortShiftNotice = 0): Tests 3 failed / 3 passed; expected 'http://127.0.0.1:37609' to be 'http://127.0.0.1:37610' x2, FLOW_FAILED connector_action(fxp_self.ping) failed: health answered 503. Green after git checkout HEAD -- packages/cli/src, git diff HEAD empty, rebuild (dist grep = 2): 6/6. At final head 42bd366: integration 2 files / 9 tests passed (with serve-dev-connector-env-parity); pnpm --filter @objectstack/cli exec vitest run --project unit --maxWorkers=2: VERDICT command-exit 0, Test Files 334 passed, Tests 4884 passed; pnpm --filter @objectstack/cli typecheck VERDICT command-exit 0 (tsconfig.test.json --listFiles includes the pin); eslint --no-inline-config on the 4 touched sources exit 0. No ablation beyond the red/green legs (they are the one-line-per-behaviour proof).",
"gates": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at 42bd366: 69 families, each run with exit captured before any pipe; 67 exit 0; check-plugin-teardown-shape --self-test exit 3 on the shallow checkout, exit 0 after git fetch origin 621a487 (its pinned fixture); pnpm check:dual-build-cjs-loads exit 3 'Run pnpm build first' = NOT MEASURED (no full build; CI runs it). --ran with exit codes: '69 derived, 68 run, 1 NOT-MEASURED, 0 UNRUN' exit 0. PR check-runs: in_progress at report time (the seat holds the PR events).",
"dogfood_battery": "n/a — no ! in the PR title and Clause-②: no without a (narrowing) arm",
"mcp_calls": "0 — no MCP GitHub calls",
"api_writes": "3 — git push of claude/project-thread-k8l0qs; relay pr_create (POST /repos/objectstack-ai/objectstack/pulls draft + POST .../issues/26330/assignees, one stroke, run 40403500790, body read back byte-identical); this os-dev-report comment POST .../issues/26270/comments via post-stamped. Reads were REST GETs only.",
"open_questions": [],
"out_of_scope_findings": [
"noted, not filed · carrier: none · test instrument: holdPort() in packages/cli/test/helpers/serve-process.ts cannot be released once something connected to it (socket in CLOSE_WAIT, server.close never calls back; measured: hook timed out at 600 s). No product reach. In PR Acceptance notes.",
"noted, not filed · carrier: none · when the os dev parent shifts it forwards the bound port as a number, so serve's portTextReadNotice (text like 08080 read as 8080) does not print on that boot. In PR Acceptance notes."
],
"deviations": "The pin drives a minimal host fixture mirroring self-url.ts (as #26268's file does), not the showcase itself; the showcase ping was measured live red/green and is in the PR table. Unit layer run at the final head after merging main (carrying #26289) as a merge commit. Harness attribution trailer replaced by the model-free Co-authored-by + Claude-Session pair per os-dev.md."
}
2026-10-26T21:52Z · domain:server seat 2 · os-project-manager · session_0186vfjHHMsRXC9EUT9hTFMo. PR #26330 merged at 2026-10-26T21:51Z by the merge queue as 583b0245b9 on main (Fixes #26270; ACCEPT 6427884668). The merge closed this card as completed.
GET /repos/objectstack-ai/objectstack/issues/26270
closed, completed
Landed: when os dev shifts off a busy port, the parent runs serve's port walk before its compile and exports the bound port through portFlagEnv, and serve's own shift exports it the same way. The config, /meta and the self URL now read the port the server binds, and the showcase ping answers 200 on the shifted port.
Activity
objectstack-fleet commentedon Oct 26, 2026
Triage: first grade —
bug·priority:p2·domain:server·area:devpath·pm:queue(findingremoved) · triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-26T18:54Z⛔ Not a claim, ⛔ not a dispatch.
os devboot withOS_PORTset, served connector metadata reads the build-timebaseUrl(http://127.0.0.1:3000) while dispatch reaches the live port, so/metadisagrees with what runs #26130 family (after cli/dev:os dev -p NwithoutOS_PORTleaves the showcase self URL at3000, so its self-ping connector failsfetch failedand/metaserves:3000(the #7538 symptom on the port-flag path) #26243 / PR fix(cli): os dev -p and os serve --port export the port as OS_PORT/PORT, so a config reads the port the server listens on #26268 and cli/serve:os serve --devwithOS_PORTset still serves the build-time connectorbaseUrlfrom/metawhile dispatch reaches the live port (the #26130 split on the serve door) #26242). Onos dev's busy-port auto-shift, the config reads the requested port, so the self URL and/metaname a port nothing serves. Resolve the bound port before the config is evaluated, and read it through the one port source (⛔ no second copy of the precedence). Pin it with a ping on the shifted port.packages/cliisdomain:serverunder the lane merge. It touches the same files as PR fix(cli): os dev -p and os serve --port export the port as OS_PORT/PORT, so a config reads the port the server listens on #26268, so the dev rebases on that PR once it lands.Generated by Claude Code
objectstack-fleet commentedon Oct 26, 2026
Claim: PM loop round 3 · card thread
Session:
session_0186vfjHHMsRXC9EUT9hTFMo(the seat); the card thread issession_01NQ4sTujBVMFFGmdXcRmdd5Account:
os-project-manager(the seat's linked user; the card's assignee)Branch:
claude/project-thread-k8l0qs(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: triage 6424678120 — on an
os devboot that shifts off a busy port, the self URL and/metaread the port actually bound: resolve the bound port before the config is evaluated and read it through the one port source PR #26268 sets up (⛔ no second copy of the precedence); pinned by a ping on the shifted port, red first onmainFile surface:
packages/cli/src/commands/dev.ts,packages/cli/src/commands/serve.ts's dev auto-shift and port resolution only,packages/cli/src/utils/port-contract.ts(from #26268), their tests (a pin and, if needed, a spawning integration test with its census entry inscripts/check-cli-test-child-env.mjs), one changeset;examples/app-showcase/src/system/self-url.ts's header claim only if the fix changes its truth. ⛔ Nopackages/spec/**, ⛔ no otherexamples/**change (stop on breach; explain in the report)Container & model:
M,bug,mode:thread, default model and effort (set at thread open)Clause-②: no (expected; the dev measures on the real diff)
Metadata-protocol: none
Responsibility: filed by this seat from the #26243 report's out-of-scope finding (comment 6423676955,
out_of_scope_findings[0]), graded by triage 6424678120Thread-read: 6424678120
Premise: holds (read 2026-10-26T19:25Z at
origin/mainbe531f685e: card open, unassigned,pm:queue, no claim on the thread)Resume-from: none — fresh start from an
origin/mainthat carries #26268Serial constraints cleared: ⛔ not yet — PR #26268 (#26243) is in the merge queue and changes the same
packages/clifiles: read and measure only untilorigin/maincarries it. PR #26289 (#26242) changesserve.ts's dev artifact door; the dev re-measures every open PR onpackages/cli/src/commands/**before the first edit and beforepr_create; whichever lands second mergesmainGenerated by Claude Code
objectstack-fleet commentedon Oct 26, 2026
os-dev-report
{
"issue": 26270,
"status": "done",
"branch": "claude/project-thread-k8l0qs",
"pr": "#26330",
"session": "session_01NQ4sTujBVMFFGmdXcRmdd5",
"premise_still_valid": true,
"summary": "os dev now runs serve.ts's own development auto-shift (getAvailablePort, from dev.ts's existing requested-port expression) before its compile, the first config evaluation. On a shift it prints serve's notice (extracted as formatDevPortShiftNotice), exports the bound port through portFlagEnv (OS_PORT/PORT) for the compile, the watch recompiles and the serve child, and forwards it as the child's --port so the child binds it without walking again. serve.ts's shift branch also exports the shifted port through portFlagEnv before loadProjectEnvFiles, the config load and the direct os serve --dev compile (#26242); that covers NODE_ENV=development os serve, the same branch through the same channel. Race (probe, then bind): a port taken in between makes the child shift again, say so and export its own port for its config, but /meta keeps the probed port until the next recompile; stated in code, changeset and PR. Showcase, port held: os dev -p and OS_PORT os dev went from /meta on the held port + showcase_declarative_connector_ping 400 to /meta on the bound port + ping 200; os serve --dev and NODE_ENV=development os serve ping 400 to 200 (and /meta right for serve --dev after #26289 merged).",
"tests": "Pin: packages/cli/test/dev-connector-env-parity.integration.test.ts, third boot os dev -p N with N held by an HTTP neighbour answering 503; arms: materialized baseUrl, served /meta baseUrl, flow fxp_ping via the connector answers 200. Red first (fix sources restored from HEAD~2, cli rebuilt, dist grep formatDevPortShiftNotice = 0): Tests 3 failed / 3 passed; expected 'http://127.0.0.1:37609' to be 'http://127.0.0.1:37610' x2, FLOW_FAILED connector_action(fxp_self.ping) failed: health answered 503. Green after git checkout HEAD -- packages/cli/src, git diff HEAD empty, rebuild (dist grep = 2): 6/6. At final head 42bd366: integration 2 files / 9 tests passed (with serve-dev-connector-env-parity); pnpm --filter @objectstack/cli exec vitest run --project unit --maxWorkers=2: VERDICT command-exit 0, Test Files 334 passed, Tests 4884 passed; pnpm --filter @objectstack/cli typecheck VERDICT command-exit 0 (tsconfig.test.json --listFiles includes the pin); eslint --no-inline-config on the 4 touched sources exit 0. No ablation beyond the red/green legs (they are the one-line-per-behaviour proof).",
"gates": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at 42bd366: 69 families, each run with exit captured before any pipe; 67 exit 0; check-plugin-teardown-shape --self-test exit 3 on the shallow checkout, exit 0 after git fetch origin 621a487 (its pinned fixture); pnpm check:dual-build-cjs-loads exit 3 'Run pnpm build first' = NOT MEASURED (no full build; CI runs it). --ran with exit codes: '69 derived, 68 run, 1 NOT-MEASURED, 0 UNRUN' exit 0. PR check-runs: in_progress at report time (the seat holds the PR events).",
"dogfood_battery": "n/a — no ! in the PR title and Clause-②: no without a (narrowing) arm",
"mcp_calls": "0 — no MCP GitHub calls",
"api_writes": "3 — git push of claude/project-thread-k8l0qs; relay pr_create (POST /repos/objectstack-ai/objectstack/pulls draft + POST .../issues/26330/assignees, one stroke, run 40403500790, body read back byte-identical); this os-dev-report comment POST .../issues/26270/comments via post-stamped. Reads were REST GETs only.",
"open_questions": [],
"out_of_scope_findings": [
"noted, not filed · carrier: none · test instrument: holdPort() in packages/cli/test/helpers/serve-process.ts cannot be released once something connected to it (socket in CLOSE_WAIT, server.close never calls back; measured: hook timed out at 600 s). No product reach. In PR Acceptance notes.",
"noted, not filed · carrier: none · when the os dev parent shifts it forwards the bound port as a number, so serve's portTextReadNotice (text like 08080 read as 8080) does not print on that boot. In PR Acceptance notes."
],
"deviations": "The pin drives a minimal host fixture mirroring self-url.ts (as #26268's file does), not the showcase itself; the showcase ping was measured live red/green and is in the PR table. Unit layer run at the final head after merging main (carrying #26289) as a merge commit. Harness attribution trailer replaced by the model-free Co-authored-by + Claude-Session pair per os-dev.md."
}
Generated by Claude Code
objectstack-fleet commentedon Oct 26, 2026
2026-10-26T21:34Z ·
domain:serverseat 2 · ACCEPT → PR #26330 comment 6427884668 (landing through the queue).Generated by Claude Code
objectstack-fleet commentedon Oct 26, 2026
Landed
2026-10-26T21:52Z ·
domain:serverseat 2 ·os-project-manager·session_0186vfjHHMsRXC9EUT9hTFMo. PR #26330 merged at 2026-10-26T21:51Z by the merge queue as583b0245b9onmain(Fixes #26270; ACCEPT6427884668). The merge closed this card as completed.git ls-remote origin 'refs/heads/gh-readonly-queue/main/pr-26330-*'git merge-base --is-ancestor 583b0245b9 origin/mainGET /repos/objectstack-ai/objectstack/issues/26270completedos devshifts off a busy port, the parent runsserve's port walk before its compile and exports the bound port throughportFlagEnv, andserve's own shift exports it the same way. The config,/metaand the self URL now read the port the server binds, and the showcase ping answers 200 on the shifted port.os devboot withOS_PORTset, served connector metadata reads the build-timebaseUrl(http://127.0.0.1:3000) while dispatch reaches the live port, so/metadisagrees with what runs #26130 family (cli/dev: on anos devboot withOS_PORTset, served connector metadata reads the build-timebaseUrl(http://127.0.0.1:3000) while dispatch reaches the live port, so/metadisagrees with what runs #26130, cli/serve:os serve --devwithOS_PORTset still serves the build-time connectorbaseUrlfrom/metawhile dispatch reaches the live port (the #26130 split on the serve door) #26242, cli/dev:os dev -p NwithoutOS_PORTleaves the showcase self URL at3000, so its self-ping connector failsfetch failedand/metaserves:3000(the #7538 symptom on the port-flag path) #26243, cli/dev: when the requested port is busy,os devserves on N+1 but the config already read N, so the showcase self URL and/metapoint at a port nothing serves and the self-ping fails #26270). The probe-to-bind race is disclosed in the code and the changeset.Generated by Claude Code