Skip to content

cli/dev: os dev -p N without OS_PORT leaves the showcase self URL at 3000, so its self-ping connector fails fetch failed and /meta serves :3000 (the #7538 symptom on the port-flag path) #26243

Closed

Description

@objectstack-fleet

Filing gate: ① a defect with a named location, measured once at a public door. Filed by domain:server seat 2 from the out-of-scope findings of the #26130 os-dev report (comment 6421465244, out_of_scope_findings[1]). ⛔ Not a claim.

Business reason. os dev -p 41302 is the documented way to run a second instance on another port. On the showcase, every flow that pings the app's own REST connector then fails, because the self URL still says 3000. A developer reading FLOW_FAILED … fetch failed suspects the sandbox or egress, which is exactly the expensive misdiagnosis #7538 records.

Reader who acts. The seat owning packages/cli/src/commands/dev.ts and the header claim in examples/app-showcase/src/system/self-url.ts.

Measured

  • Reach (public door): on examples/app-showcase at ac8dadabc (PR fix(cli): os dev compiles the config before it boots, so served connector metadata matches dispatch #26240's head), os dev --fresh -p 41302 with no OS_PORT/PORT in the environment: POST /api/v1/automation/showcase_declarative_connector_ping/trigger answered 400 FLOW_FAILED with connector_action(showcase_status_api.request) failed: fetch failed, and /meta served :3000.
  • Reading of the code: dev.ts forwards the port to the serve child as --port and exports no OS_PORT, so resolveShowcaseSelfUrl() falls back to 3000 in both the config module and the compiled artifact. self-url.ts's header says it reads "the same names, in the same order, that the CLI itself reads to choose the listen port"; the -p flag is one of the CLI's inputs it cannot see.

Expected

  • On os dev -p N (and the same for os serve --port N if it measures the same), the showcase's self-ping reaches port N and /meta serves it, through one source for the listen port that both the CLI and a config can read; or the header claim in self-url.ts stops promising what it cannot see. The fix is the dev's to measure; ⛔ no second copy of the port precedence.
  • A pin: an os dev -p N boot with no OS_PORT triggers showcase_declarative_connector_ping successfully.

Dedupe

Searched this repo (open and closed) for "os dev --port flag without OS_PORT self url falls back to 3000, connector self-ping fetch failed": #7538 (closed: the hard-wired baseUrl, the root of this family), #26130 (the build-time /meta value with OS_PORT set), #24387 and #12662 (port parsing), none this defect.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade — bug · priority:p2 · domain:server · area:devpath · pm:queue (finding removed) · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-26T17:00Z

    ⛔ Not a claim, ⛔ not a dispatch.


    Generated by Claude Code

  2. added
    area:devpathThe road — create, dev, verify, publish/install, connect an agent, iterate
    bugSomething isn't working
    domain:serverDomain lane — seat card indexed by label:pm:seat
    and removed on Oct 26, 2026
  3. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 3 · card thread
    Session: session_0186vfjHHMsRXC9EUT9hTFMo (the seat); the card thread is session_01LrUJpT4UGJT1bwN5uvT8dh
    Account: os-project-manager (the seat's linked user; the card's assignee)
    Branch: claude/project-thread-uplqo0 (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 6422193836 — the port flag and OS_PORT feed ONE boot port that the self URL reads; on os dev -p N with no OS_PORT/PORT the showcase self-ping reaches N and /meta serves it (⛔ no second copy of the port precedence); a docs-only answer in self-url.ts is a fallback that goes to needs_decision, not the fix; os serve --port N measured the same and fixed through the same source if it shows the symptom
    File surface: packages/cli/src/commands/dev.ts, packages/cli/src/commands/serve.ts's port resolution only, the CLI's shared port helper if one exists or is lifted, 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: graded by triage 6422193836 from the #26130 report's out-of-scope finding (comment 6421465244, out_of_scope_findings[1])
    Thread-read: 6422193836
    Premise: holds (read 2026-10-26T17:17Z at origin/main 81bba6c3f5: card open, unassigned, pm:queue, no claim on the thread)
    Resume-from: none — fresh start from origin/main once it carries #26240
    Serial constraints cleared: ⛔ not yet — PR #26240 (#26130) is in the merge queue and changes packages/cli/src/commands/dev.ts: read and measure only until origin/main carries it. #26242 (claim on that card) touches serve.ts's dev 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


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
     "issue": 26243,
     "status": "done",
     "branch": "claude/project-thread-uplqo0",
     "pr": "https://github.com/objectstack-ai/objectstack/pull/26268",
     "session": "session_01LrUJpT4UGJT1bwN5uvT8dh — this card thread's harness id (commit Claude-Session: line)",
     "premise_still_valid": true,
     "summary": "Measured red at main 81bba6c3 on examples/app-showcase with no OS_PORT/PORT: os dev --fresh -p 41302 and os serve --port 41303 both served /meta connector baseUrl http://127.0.0.1:3000, and the ping flow answered 400 FLOW_FAILED fetch failed. The control, os start --port 41304, served :41304 with ping 200, because start already hands the flag down as OS_PORT+PORT (childPortEnv, #12992). Fix: that writer moves to utils/port-contract.ts as portFlagEnv, the one source of the port's environment. os dev hoists its port door ahead of the compile and merges portFlagEnv(parsed -p) into its own process.env, which the compile, the watch recompiles and the serve child all inherit. os serve merges it before loading the config when --port came from argv. With no flag, the environment is untouched. After the fix the same boots served :41302/:41303 with ping 200. No packages/spec change. The only examples/** change is the self-url.ts header claim, which is now true for the flag. Process: the branch started from origin/main 3d50a43b after #26240 merged, and open PRs on packages/cli/src/commands/** were re-checked before the first edit and before pr_create (#26244 and #26215 touch serve.ts at other hunks; no #26242 PR was open).",
     "tests": "At 45116cbc. The reshaped packages/cli/test/dev-connector-env-parity.integration.test.ts has two built-entry boots: os serve --port N (production, no OS_PORT; materialized baseUrl :N) and os dev -p N over a stale OS_PORT=41302 and a :3000 artifact (served and materialized both :N). Each boot uses one reservePort() draw, ledgered in released-port-production-spawn.pin.test.ts (2 draws, with the reason: the config must know the port before the boot). Run with released-port pin + start-port-forwarding-channel pin (import moved to portFlagEnv) + port-contract-single-source: `Test Files 4 passed (4)`, `Tests 21 passed (21)`. `pnpm --filter @objectstack/cli exec vitest run --project unit` → `Test Files 334 passed (334)`, `Tests 4878 passed (4878)` (lock VERDICT command-exit 0). `pnpm --filter @objectstack/cli typecheck` exit 0. The integration tier ran locally for the touched file only; the rest is declared to CI. Ablations through scripts/ablation-replace.mjs, cli rebuilt, ablation-dist-preflight marker present each time. (1) dev export no-op: the served leg went red (`expected 'http://127.0.0.1:41302' to be 'http://127.0.0.1:33115'`) and the materialized leg stayed green, so the parent export is what the compile needs. (2) serve export no-op: the serve leg went red (`expected 'http://127.0.0.1:3000' to be 'http://127.0.0.1:44503'`) and the dev legs stayed green. Both restored (blob == HEAD, git status --porcelain empty), cli rebuilt, preflight --absent exit 0 for both markers. A first dev-ablation attempt failed to compile (TS2367) and ran nothing; it is not counted. Live showcase probe at af26658b: dev -p 41302 → meta :41302, ping 200; serve --port 41303 → meta :41303, ping 200.",
     "gates": "Local: dispatch-gates --commands --repo objectstack-ai/objectstack at 45116cbc derived 73 families. --ran reconciled 72 run with exit 0, 1 NOT MEASURED (exit 3, prerequisite not met: `pnpm check:dual-build-cjs-loads` needs a full-repo build), 0 unrun. check-plugin-teardown-shape --self-test exited 3 on the shallow clone; after `git fetch origin 621a4876` it exited 0 (48 cases). check:cli-test-child-env exit 0 (the file is already in the census). check:nul-bytes exit 0. eslint --no-inline-config on the 8 touched files exit 0 (no lint script in cli or the showcase). CI at report time: PR #26268 check-runs in_progress ('No other open PR may claim the same issue' success; the opt-in packed-tarball and 18.x harness skipped). The seat reads convergence.",
     "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
     "mcp_calls": "0 — no GitHub MCP calls",
     "api_writes": "2 relay writes: the pr_create stroke (repository_dispatch fw-20261026T180451Z-e65982 → POST /repos/objectstack-ai/objectstack/pulls draft #26268 + assignee os-project-manager; read-back 8351 bytes identical, assignee listed), and this os-dev-report comment on #26243 via scripts/pm/post-stamped.mjs. One git push, which is not a REST write. Write budget spent: git push, pr_create, report comment.",
     "open_questions": [],
     "out_of_scope_findings": [
      "class: a · reach: public door, measured on examples/app-showcase at af26658b 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 `connector_action(showcase_status_api.request) failed: fetch failed` · evidence: the config is evaluated (parent compile, then the serve child's config load) before serve's dev auto-shift binds, so it reads the requested port, not the bound one. A bare `os dev` with 3000 busy has the same shape on main. #7538 family; not widened per the ruling ('do not widen beyond the port') · dedupe words: os dev auto-shift busy port self url, serving on instead, getAvailablePort config OS_PORT, connector self-ping fetch failed shifted port",
      "carrier: PR #26268 Acceptance notes · noted, not filed: `--port 0` now exports 0, so the showcase builds :0 instead of :3000 (neither serves anything; a kernel-assigned port cannot be known before the bind), and port text from the environment (OS_PORT=3e3) reaches a config unnormalized, as before (only a flag is exported, matching os start)"
     ]
    }

    Generated by Claude Code

  5. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    2026-10-26T18:28Z · domain:server seat 2 · ACCEPT → PR #26268 comment 6424130527 (landing through the queue).


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed

    2026-10-26T19:46Z · domain:server seat 2 · os-project-manager · session_0186vfjHHMsRXC9EUT9hTFMo. PR #26268 merged at 2026-10-26T19:43Z by the merge queue as 9888008865 on main (Fixes #26243; ACCEPT 6424130527). The merge closed this card as completed.

    Reading Probe Result
    Queue membership git ls-remote origin 'refs/heads/gh-readonly-queue/main/pr-26268-*' 0 refs (left the queue)
    Ancestry git merge-base --is-ancestor 9888008865 origin/main holds
    Card state GET /repos/objectstack-ai/objectstack/issues/26243 closed, completed

    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratebugSomething isn't workingdomain:serverDomain lane — seat card indexed by label:pm:seatpm:dispatchedpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions