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: a --no-server boot prints "[datasource-admin] route registration failed: … a composition/ordering fault" when nothing is at fault; the plugin's own degrade line is unreachable because getService throws #24022
Filing gate ①, class (a) (user-visible misleading text). reach:measured at the public doorobjectstack serve objectstack.config.ts --no-server --preset minimal (production, a host fixture), by #23744's dev on base adce192974 and on c29a1d1f90 (os-dev-report6222472811, out_of_scope_findings[0]). The seat re-read the code on origin/main.
Filed by domain:cli seat 1 (#6024) · marchtian · session session_01PFB9ZGRWYvjhTXsd8i6KBp, from that report. ⛔ Not a claim. Grade and lane are triage's.
What the operator reads
On a --no-server boot, the banner's boot diagnostics print:
WARN [datasource-admin] route registration failed: [Kernel] Service 'http.server' not found (while plugin 'com.objectstack.cli.datasource-admin-routes' was initializing — a composition/ordering fault; registration order is not a contract.)
Nothing is at fault. --no-server composed no HTTP server on purpose, so the datasource admin routes have nowhere to mount. The line tells the operator to look for an ordering bug that does not exist.
Why, read on origin/main
packages/cli/src/commands/serve.ts, the com.objectstack.cli.datasource-admin-routes plugin (about :5053-:5079), init reads ctx.getService?.('http.server') ?? ctx.getService?.('http-server'). It means to fall through to its own degrade line, [datasource-admin] http.server unavailable; REST routes not installed, when no server is composed.
getService THROWS on an unregistered name; it does not return undefined. The same file documents this trap at :542 and :711, beside readComposedHttpServer. So the ?? never runs, the throw lands in the catch, and the catch prints "route registration failed" with the kernel's ordering-fault wording.
The intended degrade line is unreachable on every boot without an HTTP server.
Reader who acts
Triage grades and routes it. The landing is the plugin's init in serve.ts (domain:cli). One shape: read the server the way readComposedHttpServer does, so a boot without a server takes the plugin's own degrade line, and a real registration failure on a composed boot still warns. Pin the --no-server shape (no "route registration failed", no "ordering fault") and its control: a composed boot still mounts /api/v1/datasources.
Dedupe
REST list of domain:cli issues (open and closed, 100 newest) with datasource-admin, ordering fault or http.server not found in the title: 0.
Triage seat (objectstack-wide, seat post #6015). ⛔ Not a claim, ⛔ not a dispatch.
Why p3: a misleading boot-diagnostic line on a --no-server boot, when nothing is at fault. Nothing is refused or lost. The fleet's queue currently runs p1 and p2.
Claim: PM loop, serial dispatch, p3 only (the maintainer to this seat, latest: 「当前任务处理完,后续只派p3卡」; #23932 landed as 5c2ac83a23 and this seat has nothing in flight). Label order among priority:p3pm:queue bugs in domain:cli, read in this act: #24022 is the oldest. #24022: a boot that composes no HTTP server stops printing "[datasource-admin] route registration failed: … a composition/ordering fault", and takes the plugin's own degrade line, because the plugin reads the server without the throwing getService · 2026-10-16T21:29Z
Session: session_01PFB9ZGRWYvjhTXsd8i6KBp
Account: marchtian (the seat's linked user as GET /user answers it; always the card's assignee)
Branch: claude/issue-24022-datasource-admin-no-server
Worktree: objectstack-issue-24022
Domain: domain:cli
Seat: domain:cli#1 (seat post #6024)
File surface (read on origin/main5c2ac83a23; line numbers move; stop on a breach and explain it in the report):
packages/cli/src/commands/serve.ts: the com.objectstack.cli.datasource-admin-routes plugin's init (about :5111-:5135) only, and its reading of http.server.
Its pins (new tests beside it under packages/cli/src/**), and one .changeset/24022-*.md.
Claim: PM loop round 1 (takeover of #24022: a boot that composes no HTTP server stops printing "[datasource-admin] route registration failed: … a composition/ordering fault", and takes the plugin's own degrade line) · 2026-10-17T01:46Z
Session: session_01BVm1pAXVXQ3PjC42j1kPFf
Account: os-sales (the seat's linked user as GET /user answers it; the card's assignee from this act)
Branch: claude/issue-24022-datasource-admin-no-server
Worktree: objectstack-issue-24022
Domain: domain:cli
Seat: domain:cli#1 (seat post #6024, takeover marker 6228090725)
Release: claim 6225067779 · session session_01PFB9ZGRWYvjhTXsd8i6KBp · account marchtian · 因: the claimant is unreachable (its session has ended, per the maintainer's confirmation in 6228090725) · 去向: this claim, same branch, same file surface · 出处: the maintainer, in session session_01BVm1pAXVXQ3PjC42j1kPFf's chat, verbatim 「24022 你也接手。」
Resume-from: claude/issue-24022-datasource-admin-no-server@4b0a631575da00dde1f5b03dc527dac18f4babae
Handover record: the released claim's dev pushed five commits by 2026-10-16T22:32Z, the last 4b0a631575. They are 7177b4e8c (the fix in the plugin's init in serve.ts), 2e52e010a (a new serve-datasource-admin-routes.test.ts and cases in serve-no-server-banner.integration.test.ts), acd285a2b (.changeset/24022-datasource-admin-no-server.md), 16be28cdd (scripts/slot-lookup-baseline.json, serve.ts ratcheted 9 → 7), and 4b0a631575 (a merge of origin/main). No PR was opened and no os-dev-report was posted, so all of it is UNVERIFIED and is re-run in full. origin/main is now d6bd98a3f; since the branch's last merge it gained 570c7a2d9 (#24088, Fixes #23858), which edits serve.ts's runtime state file write. git merge-tree reads the merge as clean.
File surface (unchanged from 6225067779, plus the derived ratchet file the dev touched; re-read on origin/maind6bd98a3f; stop on a breach and explain it in the report):
packages/cli/src/commands/serve.ts: the com.objectstack.cli.datasource-admin-routes plugin's init only, and its reading of http.server.
Its pins: packages/cli/src/commands/serve-datasource-admin-routes.test.ts (on the branch) and the cases on the branch in packages/cli/src/commands/serve-no-server-banner.integration.test.ts; one .changeset/24022-*.md (on the branch).
scripts/slot-lookup-baseline.json: derived; only serve.ts's row, and only downward.
os-dev-report
{
"issue": 24022,
"status": "done",
"branch": "claude/issue-24022-datasource-admin-no-server",
"pr": "#24132",
"session": "session_01BVm1pAXVXQ3PjC42j1kPFf — subagent run, so this is the parent PM session's id (dispatch claim 6228120195)",
"premise_still_valid": true,
"summary": "RESUME of claude/issue-24022-datasource-admin-no-server@4b0a631575, newest Claim 6228120195 names this branch (checked). The worktree was built from origin/BRANCH and merged origin/main 50ccfa6 (merge b794db1, clean, no os-regen deferral). Every handover commit was read hunk by hunk. Kept: 7177b4e (the fix; the new unit file landed in THIS commit, not in 2e52e01 as the handover record says), 2e52e01 (integration cases) and 16be28c (slot-lookup serve.ts 9 to 7, re-measured after the merge, check:slot-lookup holds). Corrected: acd285a's changeset alias sentence; it now says the http-server fallback never ran. Added: commit a12bf2f, a shape 4 control backing the changeset's claim that the routes mount on a config-mounted HonoServerPlugin under --no-server. The fix: the datasource-admin plugin moves from inline in run() to an exported factory createDatasourceAdminRoutesPlugin in serve.ts (same name, version, optionalDependencies). Its init reads the server through the existing readComposedHttpServer (reused, unchanged), so a boot without a server takes the degrade line, and a registration that throws on a composed boot still warns. PM mechanism assumptions, all 3 MEASURED TRUE. (1) ctx.getService throws '[Kernel] Service ... not found' plus the describeInitOrderFault suffix (packages/core/src/kernel.ts, plugin-order.ts); the unit premise case pins it on a real ObjectKernel. (2) The ablation reproduces the card's exact WARN line at the door through the built CLI. (3) #24088's serve.ts hunks sit at about :11 and :1094; this diff sits at about :5110 and :5771. files_changed vs origin/main 50ccfa6 (5 files, +287/-35): packages/cli/src/commands/serve.ts; packages/cli/src/commands/serve-datasource-admin-routes.test.ts (new); packages/cli/src/commands/serve-no-server-banner.integration.test.ts; .changeset/24022-datasource-admin-no-server.md (cli patch); scripts/slot-lookup-baseline.json (serve.ts row only, 9 to 7). File surface: no breach. The factory extraction is the same plugin in the same file, relocated beside createUnknownHostnameGuardPlugin; no hold-off symbol was edited. line_budget: n/a (no skills/** touched). labels: 0 written; the dispatch named none, and skip-changeset does not apply. deviations: (a) fetched the teardown self-test's pinned fixture commit 621a487 with --depth=1, which adds an object and a shallow root to the shared .git; (b) origin/main moved to c1c0a90 after the merge (3 commits, packages/rest, plugin-email, qa/dogfood, runtime test, spec/liveness; none under packages/cli); merge-tree clean, NOT merged; (c) the first git push was an up-to-date no-op, so the write route was first proven by the merge push; (d) test:repo not run locally (CI's), and check:dev-prereqs and check:skill-frame-freshness not run (no packages/spec or four-axis framework file in the diff); (e) the PR body was written once at pr_create and never patched. Cleanup done: worktree node_modules removed, git worktree remove without --force exited 0, no server left running.",
"tests": "All at head a12bf2f; every exit was captured before any pipe and read from the os-verify-lock VERDICT line. (1) Unit tier: pnpm --filter @objectstack/cli exec vitest run --project unit --maxWorkers=2. 'Test Files 309 passed (309) / Tests 4588 passed (4588)', VERDICT command-exit 0. (2) New unit file, src/commands/serve-datasource-admin-routes.test.ts: 'Tests 6 passed (6)', exit 0; import 18.80s, tests 14ms on a shared box. A sibling serve importer (serve-unknown-hostname-guard.test.ts) measured the same, 36.64s of import for the two files together. (3) Integration tier, run on the touched file only, as the dispatch requires: pnpm --filter @objectstack/cli exec vitest run --project integration --maxWorkers=2 src/commands/serve-no-server-banner.integration.test.ts. 'Tests 4 passed (4)', tests 12.68s, exit 0, against the built CLI (turbo build --filter=@objectstack/cli, 61 tasks, exit 0). Other integration-tier files are declared to CI. (4) pnpm --filter @objectstack/cli typecheck: TYPECHECK_EXIT=0, including 'check:test-typecheck: OK'. tsc --noEmit --listFiles names both touched test files (count 2). (5) Ablation, once, on the changed behaviour; fix committed first. scripts/ablation-replace.mjs put the pre-fix read back (throwing getService chain inside the try): anchor x1 to x0, blob a48fc3da93e4 to 95b1a98c5f93. The CLI was rebuilt (BUILD_EXIT=0), and ablation-dist-preflight @objectstack/cli 'readComposedHttpServer(ctx)' --absent passed (PREFLIGHT_EXIT=0; dist old-chain count 2). Unit file: 'Tests 1 failed | 5 passed', failing 'takes its own degrade line'. Integration file: 'Tests 2 failed | 2 passed'; shapes 1 and 2 failed, each printing the card's 'WARN [datasource-admin] route registration failed: [Kernel] Service 'http.server' not found (while plugin 'com.objectstack.cli.datasource-admin-routes' was initializing — a composition/ordering fault; ...)'; both controls green. Direction as predicted. Restore: blob == HEAD a48fc3da93e4, git diff HEAD empty, git status --porcelain empty. Rebuilt, preflight found the marker present (PREFLIGHT_EXIT=0), unit 6/6 and integration 4/4, exits 0. Unit case 3 (only http.server asked) stays green under the mutation. It guards against an alias read coming back, not against this card's defect. (6) Door, built CLI, host fixture: 'os serve objectstack.config.ts --no-server --preset minimal' printed 'WARN [datasource-admin] http.server unavailable; REST routes not installed' and no ordering fault.",
"gates": "Local subset at head a12bf2f. Derived with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no paths; stderr: tree objectstack-ai/objectstack at the branch head, 5 paths vs merge base 50ccfa6): 75 commands, each run with its exit recorded before any pipe. 72 exited 0 on the first pass. 3 exited 3 (PREREQUISITE NOT MET) and exited 0 once the prerequisite was met: check-plugin-teardown-shape --self-test (fixture commit unreachable on the shallow clone; fetched --depth=1, then '48 cases pass'), pnpm check:dual-build-cjs-loads and pnpm check:i18n-coverage (missing dists; full turbo build, then 'OK (14 config(s), 621 baselined untranslated string(s), none new)'). dispatch-gates --ran: 'Run reconciliation — 75 derived, 75 run, 0 NOT-MEASURED, 0 UNRUN', RAN_EXIT=0. Key verdict lines: check:slot-lookup 'slot-lookup ratchet holds: 102 unswept site(s) in 25 file(s), none new'; check:test-source-alias OK; check:cross-package-test-inputs OK; check-empty-changeset 1 declaring changeset added. Lint blind spot: pnpm exec eslint --no-inline-config on the 3 changed .ts files, EXIT=0 with no output; the .md and .json are outside eslint's configured set (0 errors, 2 'File ignored' warnings). Extra, outside the derived set: pnpm check:startup-registry-verdict EXIT=0 ('45 startup/open-registry seam(s) ... none recording a verdict the boot can contradict'); node scripts/check-nul-bytes.mjs EXIT=0; manual control-byte grep over the 5 files, 0 hits. CI on PR 24132 head a12bf2f, read once and not waited on. completed/success: Governed Surface Queue Guard, Check Changeset, The card this PR closes must claim this branch, Part-of PR must not also close its card, No other open PR may claim the same issue, No other open PR may claim the same single-writer path, Check PR Size, Check Documentation Links, Flag docs affected by code changes, filter, Auto Label, Dogfood Regression Gate. in_progress: Build Core; Test Core (1/6 to 6/6); Type Check · workspace / source gates / consumer gates / debt ledger; Lint · ESLint / repo & tooling gates / docs & code guards / CI, release & engine gates / PM dispatch-gates / scoped · tooling self-tests / scoped · slot lookup & corpus / scoped · query-options erasure. skipped: Packed-tarball smoke (opt-in), Console Pin Gate, Temporal Conformance, Build Docs, Dogfood Verify CLI, Dogfood Regression Gate shards.",
"mcp_calls": "0 — no MCP GitHub tool was called",
"api_writes": "5 REST writes in 2 relay strokes: 2 seat-side POST /repos/objectstack-ai/objectstack/dispatches, and 3 writes the fleet-write relay executed as objectstack-fleet[bot]. Stroke 1 (pr_create, run 38994916698, success): POST /repos/objectstack-ai/objectstack/pulls (draft) + POST /repos//issues/24132/assignees (os-sales); read-back: 8486 bytes sent, 8486 stored, identical. Stroke 2 (this comment): POST /repos//issues/24022/comments. Not REST: 3 git push (no-op probe, merge b794db1, a12bf2f). 0 label writes. 0 PATCH.",
"open_questions": [],
"out_of_scope_findings": [
"class: a · reach: public door, built CLI at a12bf2f with a host fixture: 'OS_ROOT_DOMAIN=example.test os serve objectstack.config.ts --no-server --preset minimal' prints 'WARN [unknown-hostname-guard] install failed {"error":"[Kernel] Service 'http.server' not found (while plugin 'com.objectstack.cli.unknown-hostname-guard' was initializing — a composition/ordering fault; registration order is not a contract.)"}' when nothing is at fault · evidence: packages/cli/src/commands/serve.ts createUnknownHostnameGuardPlugin init (about :5956) reads ctx.getService?.('http.server') ?? ctx.getService?.('http-server') inside its try, and its catch (about :6121) warns 'install failed'. It is this card's defect class in the sibling plugin, and its own degrade line '[unknown-hostname-guard] http.server unavailable; guard not installed' is just as unreachable. Landing: that plugin's init in serve.ts (domain:cli); the shape is readComposedHttpServer, with a --no-server pin in serve-unknown-hostname-guard.test.ts. Not fixed in place: outside this claim's declared file surface (the datasource-admin plugin's init only), which only the seat can amend · dedupe words: unknown-hostname-guard install failed no-server; OS_ROOT_DOMAIN ordering fault http.server not found; hostname guard getService throws optional chain"
]
}
⛔ Not a new claim; the branch, account and seat are unchanged.
Added to the file surface:packages/cli/src/commands/serve.ts, createUnknownHostnameGuardPlugin's init, its read of http.server only; its pins in packages/cli/src/commands/serve-unknown-hostname-guard.test.ts; and the same .changeset/24022-datasource-admin-no-server.md.
Why: PR fix(cli): a --no-server boot takes the datasource admin routes' own degrade line, not an ordering fault #24132's dev measured the same defect in the sibling plugin, at the door on the built CLI. OS_ROOT_DOMAIN=example.test os serve objectstack.config.ts --no-server --preset minimal prints WARN [unknown-hostname-guard] install failed {"error":"[Kernel] Service 'http.server' not found (while plugin 'com.objectstack.cli.unknown-hostname-guard' was initializing — a composition/ordering fault; …)"}. Its own degrade line, [unknown-hostname-guard] http.server unavailable; guard not installed, is just as unreachable.
The family, read on origin/mainc1c0a9094:git grep -nE "getService\?\.\(\s*['\"]http[.-]server['\"]\s*\)\s*\?\?" over non-test packages/**/*.ts gives 3 hits. One is readComposedHttpServer itself (serve.ts:550, inside its try). The other two are serve.ts:5127 (this card's plugin, fixed by PR fix(cli): a --no-server boot takes the datasource admin routes' own degrade line, not an ordering fault #24132) and serve.ts:5928 (the guard). The radius is that single-line spelling. The one other alias read, cloud-connection-plugin.ts:157, is already inside a try and is outside this defect class.
The four conditions: the same defect class; a mechanical fix whose shape this PR already pins (readComposedHttpServer); no other claim holds serve.ts; the same gate families. After this, no member of the family is left.
os-dev-report
{
"issue": 24022,
"status": "done",
"branch": "claude/issue-24022-datasource-admin-no-server",
"pr": "#24132",
"session": "session_01BVm1pAXVXQ3PjC42j1kPFf — subagent run, so this is the parent PM session's id (dispatch claim 6228120195, file surface amendment 6228552643)",
"premise_still_valid": true,
"summary": "PATCH ROUND 1. The newest Claim is still 6228120195, naming this branch, and amendment 6228552643 was read first. The worktree was recreated from origin/BRANCH at a12bf2f. Main (c1c0a90) was NOT merged: there was no conflict and no main-caused red, and none of it touches packages/cli. New commit 6c33626 (pushed): createUnknownHostnameGuardPlugin's init now reads the server through readComposedHttpServer. It is a one-line hunk; the read stays inside the existing try, which readComposedHttpServer never throws out of; readComposedHttpServer itself is unchanged. A no-server boot now takes '[unknown-hostname-guard] http.server unavailable; guard not installed', and an install that throws on a composed server still warns 'install failed'. Pins in serve-unknown-hostname-guard.test.ts. Changeset amended: still one @objectstack/cli patch, now naming the guard's line too. slot-lookup: serve.ts 7 to 6, only that row. Family radius on 6c33626: the seat's grep (getService?.('http[.-]server') ??, non-test packages/**/*.ts) now hits only readComposedHttpServer itself (serve.ts:550, inside its try). files_changed vs origin/main 50ccfa6 (6 files, +404/-42): packages/cli/src/commands/serve.ts; packages/cli/src/commands/serve-datasource-admin-routes.test.ts; packages/cli/src/commands/serve-no-server-banner.integration.test.ts; packages/cli/src/commands/serve-unknown-hostname-guard.test.ts; .changeset/24022-datasource-admin-no-server.md; scripts/slot-lookup-baseline.json. This round's diff (a12bf2f..6c33626): serve.ts 1 line, the guard test file +118/-6, the changeset, and the baseline row. File surface: within the amended surface. line_budget: n/a. labels: 0 written. Restart: the container restart cut the derived gate loop at 67/75, all 67 exit 0. Commands 68-75 were re-run in the foreground on 6c33626 and appended to the same record. Every other step had finished before the restart, with its verdict line recorded at 6c33626: unit tier, typecheck, eslint, integration file, both ablation legs, door. They were not re-run. deviations: (a) the derivation warns STALE TREE: 6c33626 is 3 commits behind origin/main, and 3 family files changed there (scripts/check-route-envelope.mjs, scripts/engine-double-contract.pinned.json, scripts/adr-anchors/packages__rest__src__form-routes.ts.json). Their families ran the branch's copies, kept that way per the order not to merge; CI's merge-ref run reads main's copies. (b) The guard ablation was not rebuilt, because its subject is imported from src via the relative ./serve.js. (c) A fresh worktree has no dist: the first guard test run failed to resolve @objectstack/core (a prerequisite, not a measurement); a full turbo build (71/76 cached) fixed it before every reading. (d) The PR body was NOT patched; the exact edits are in pr_body_edits. Cleanup done: door fixtures deleted, worktree node_modules removed, git worktree remove without --force exited 0, no server or watcher left running. PR body edits for the seat, also in pr_body_edits: [The fix] replace the intro line, insert one bullet after the alias bullet, and replace the slot-lookup bullet. [Pins] append one bullet after the integration bullet. [Acceptance notes] drop the line that opens '- The same defect is in the sibling plugin in this file, the unknown-hostname guard.' Recommended, not ordered: replace the '## Verification, all at head a12bf2f' section with verification_replace and add abl2_add after the round-1 ablation subsection, since the round-1 numbers name the old head.",
"tests": "All at head 6c33626; every exit was captured before any pipe and read from the os-verify-lock VERDICT line. (1) Unit tier: pnpm --filter @objectstack/cli exec vitest run --project unit --maxWorkers=2. 'Test Files 309 passed (309) / Tests 4591 passed (4591)', VERDICT command-exit 0 (4588 in round 1, +3 cases). (2) Guard file plus datasource file: 'Test Files 2 passed (2) / Tests 44 passed (44)', exit 0; the guard file alone is 38 of 38. (3) Integration file, re-run on the final head with a CLI built from it: 'Tests 4 passed (4)', exit 0. (4) pnpm --filter @objectstack/cli typecheck, joined with tsc --noEmit --listFiles by &&: VERDICT command-exit 0, 'check:test-typecheck: OK'. listFiles names all 3 touched test files. (5) Ablation, round 2, on the guard; fix committed first. scripts/ablation-replace.mjs: anchor x1 to x0, blob a080f01a90c5 to a48fc3da93e4 (byte-identical to the a12bf2f serve.ts, so the mutation is exactly the pre-fix line). Mutated: 'Tests 2 failed | 36 passed (38)', UNIT_EXIT=1. The failures are 'no server composed: the degrade line, once' (it received '[unknown-hostname-guard] install failed {"error":"[Kernel] Service 'http.server' not found (while plugin 'com.objectstack.cli.unknown-hostname-guard' was initializing — a composition/ordering fault; registration order is not a contract.)"}') and the throwing-resolution case. Both controls stayed green; direction as predicted. Restore: blob == HEAD a080f01a90c5, git diff HEAD empty, git status --porcelain empty, 38/38, UNIT_EXIT=0. (6) Door, built CLI carrying both fixes (dist old-chain count 0, readComposedHttpServer(ctx) count 2), OS_ROOT_DOMAIN=example.test. '--no-server --preset minimal' printed 'WARN [unknown-hostname-guard] http.server unavailable; guard not installed' and 'WARN [datasource-admin] http.server unavailable; REST routes not installed', no ordering fault. A default boot (OS_LOG_LEVEL=info) and a '--no-server --preset minimal' boot with a config-mounted HonoServerPlugin each logged 'INFO [unknown-hostname-guard] installed {"rootDomain":"example.test"}' and no guard warning. This backs the changeset's 'installs the hostname guard as before, including under --no-server when the config mounts its own HonoServerPlugin'. Round-1 readings (a12bf2f: datasource ablation, 4588 tests) stay in the first os-dev-report, 6228522842.",
"gates": "Local subset at head 6c33626. node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no paths; stderr: tree objectstack-ai/objectstack at commit 6c33626, 6 paths vs merge base 50ccfa6, plus the STALE TREE warning in summary deviation (a)) derives 75 commands, the same set as round 1. All 75 exit 0: 67 before the restart, 68-75 re-run in the foreground after it. dispatch-gates --ran: 'Run reconciliation — 75 derived, 75 run, 0 NOT-MEASURED, 0 UNRUN', RAN_EXIT=0. Key lines: check:slot-lookup 'slot-lookup ratchet holds: 101 unswept site(s) in 25 file(s), none new'; check:route-envelope green; check:engine-double-contract 'OK — 1017 pinned'. eslint --no-inline-config on the 4 changed .ts files: ESLINT_EXIT=0, no output. Extra: pnpm check:startup-registry-verdict EXIT=0 ('44 startup/open-registry seam(s) ... none recording a verdict the boot can contradict'); manual control-byte grep over the 6 files, 0 hits. CI on PR 24132 head 6c33626, read once and not waited on. success (32): Lint & Repo Gates, TypeScript Type Check, Build Core, Governed Surface Queue Guard, Check Changeset, Test Core 1/6, 2/6, 4/6, 5/6 and 6/6, all Lint · and Type Check · lanes, Dogfood Regression Gate, Check PR Size, Check Documentation Links, Flag docs affected by code changes, the three claim/closing guards, the two single-writer guards, Auto Label, filter. in_progress: Test Core (3/6). skipped: Build Docs, Console Pin Gate, Dogfood shards, Dogfood Verify CLI, Packed-tarball smoke, Temporal Conformance.",
"mcp_calls": "0 — no MCP GitHub tool was called",
"api_writes": "This round: 2 REST writes in 1 relay stroke, a seat-side POST /repos/objectstack-ai/objectstack/dispatches and the relay's POST /repos//issues/24022/comments (this report). Not REST: 1 git push (a12bf2f..6c33626). 0 PATCH (PR body untouched), 0 label writes. Round 1's 5 REST writes are in report 6228522842.",
"open_questions": [],
"out_of_scope_findings": [],
"pr_body_edits": {
"fix_intro_replace": {
"old": "packages/cli/src/commands/serve.ts only, the com.objectstack.cli.datasource-admin-routes plugin:",
"new": "packages/cli/src/commands/serve.ts only, in two plugins: com.objectstack.cli.datasource-admin-routes, and its sibling com.objectstack.cli.unknown-hostname-guard:"
},
"fix_insert_after_alias_bullet": "- The unknown-hostname guard (createUnknownHostnameGuardPlugin, composed when OS_ROOT_DOMAIN is set) had the same trap, so its init now reads the server through readComposedHttpServer too. It is a one-line hunk. The read stays inside the existing try, and readComposedHttpServer never throws. With no server, the boot now takes [unknown-hostname-guard] http.server unavailable; guard not installed. On a composed server whose install throws, it still warns install failed with the error. The claim's file surface was widened for this in comment 6228552643.",
"fix_slot_lookup_replace": {
"old": "- scripts/slot-lookup-baseline.json: serve.ts 9 to 7, because the untyped two-lookup chain is gone (check:slot-lookup holds at 102 sites in 25 files).",
"new": "- scripts/slot-lookup-baseline.json: serve.ts 9 to 6, because both untyped two-lookup chains are gone (check:slot-lookup holds at 101 sites in 25 files)."
},
"pins_append_after_integration_bullet": "- packages/cli/src/commands/serve-unknown-hostname-guard.test.ts (unit tier, the guard's existing file):\n 1. a real ObjectKernel boot with no server: no install failed, no ordering fault, and exactly one [unknown-hostname-guard] line, the degrade line;\n 2. CONTROL: a real kernel boot with a composed server, ordered ahead by optionalDependencies, logs installed, prints no [unknown-hostname-guard] warning, and refuses an unmapped host with 404 ENVIRONMENT_NOT_FOUND;\n 3. CONTROL: a usable server whose raw app refuses the middleware still warns install failed, naming the error;\n 4. the existing throwing service-resolution case now expects the degrade line instead of install failed. The kernel throws on an unregistered name, so a throwing read IS the no-server boot.",
"acceptance_notes_drop": "- The same defect is in the sibling plugin in this file, the unknown-hostname guard. Its init reads http.server through the same throwing chain. Measured at the door: OS_ROOT_DOMAIN=example.test os serve objectstack.config.ts --no-server --preset minimal prints WARN [unknown-hostname-guard] install failed {\"error\":\"[Kernel] Service 'http.server' not found (while plugin 'com.objectstack.cli.unknown-hostname-guard' was initializing — a composition/ordering fault; ...)\"}. It is outside this claim's file surface, so it is not changed here. It goes to the seat as a finding.",
"verification_replace_recommended": "## Verification, all at head 6c33626a8\n\n- Unit tier: pnpm --filter @objectstack/cli exec vitest run --project unit --maxWorkers=2 reads 309 files, 4591 tests, all passed, exit 0.\n- Integration, the touched file: pnpm --filter @objectstack/cli exec vitest run --project integration --maxWorkers=2 src/commands/serve-no-server-banner.integration.test.ts reads 4 of 4 passed, exit 0. The other integration-tier files are declared to CI.\n- pnpm --filter @objectstack/cli typecheck exits 0, check:test-typecheck included. tsc --noEmit --listFiles compiles all three touched test files.\n- pnpm exec eslint --no-inline-config on the four changed .ts files exits 0 with no output. The .md and .json files are outside eslint's configured file set.\n- Gates: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derives 75 commands on 6c33626a8, and all 75 exit 0. --ran reads 75 derived, 75 run, 0 NOT-MEASURED, 0 UNRUN.\n - The derivation warns that the tree is 3 commits behind origin/mainc1c0a9094, where 3 family files changed: check-route-envelope.mjs, engine-double-contract.pinned.json and one scripts/adr-anchors file. Those families ran the branch's copies. CI's merge-ref run is the reading on main's copies.\n - Also run, outside the derived set: check:startup-registry-verdict (exit 0, 44 seams, none recording a verdict the boot can contradict).\n- At the door, against the built CLI, with OS_ROOT_DOMAIN=example.test:\n - os serve objectstack.config.ts --no-server --preset minimal prints WARN [unknown-hostname-guard] http.server unavailable; guard not installed and WARN [datasource-admin] http.server unavailable; REST routes not installed, and no ordering fault;\n - a default boot, and a --no-server boot whose config mounts its own HonoServerPlugin, each log INFO [unknown-hostname-guard] installed, with no guard warning.",
"ablation_round2_append_recommended": "### Ablation, round 2 (the guard)\n\nThe fix was committed first (6c33626a8). scripts/ablation-replace.mjs put the guard's pre-fix line back. The anchor count went from 1 to 0, and the blob went from a080f01a90c5 to a48fc3da93e4, which is byte-identical to the previous head's serve.ts. The test imports its subject from source (./serve.js), so no rebuild sits in the path.\n\n- Mutated leg: the guard file reads 2 failed, 36 passed. Both failures are the cases that read a throwing service as no server: the real-kernel no-server boot, which received the exact [unknown-hostname-guard] install failed ... a composition/ordering fault line, and the throwing-resolution case. Both controls stayed green.\n- Restore leg: blob back to the HEAD blob, git diff HEAD empty, git status --porcelain empty. 38 of 38 passed."
}
}
27d7c2aa1 "fix(cli): a --no-server boot takes the datasource admin routes' own degrade line, not an ordering fault (#24132)"; git rev-list --parents -n1 gives 1 parent, a squash
the open domain:cli set lost #24022 only, so no other card was closed by a keyword
State: closed completed by Fixes #24022; pm:dispatched stripped in this act. Both members of the family, the datasource admin routes and the unknown-hostname guard, are on main.
For triage: finding is still on this closed card. It is triage's label.
Activity
objectstack-fleet commentedon Oct 16, 2026
Triage: first grade,
bug·priority:p3·domain:cli·area:devpath·pm:queue· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-16T20:01ZTriage seat (objectstack-wide, seat post #6015). ⛔ Not a claim, ⛔ not a dispatch.
--no-serverboot, when nothing is at fault. Nothing is refused or lost. The fleet's queue currently runs p1 and p2.objectstack-fleet commentedon Oct 16, 2026
Claim: PM loop, serial dispatch, p3 only (the maintainer to this seat, latest: 「当前任务处理完,后续只派p3卡」; #23932 landed as
5c2ac83a23and this seat has nothing in flight). Label order amongpriority:p3pm:queuebugs indomain:cli, read in this act: #24022 is the oldest. #24022: a boot that composes no HTTP server stops printing "[datasource-admin] route registration failed: … a composition/ordering fault", and takes the plugin's own degrade line, because the plugin reads the server without the throwinggetService· 2026-10-16T21:29ZSession:
session_01PFB9ZGRWYvjhTXsd8i6KBpAccount:
marchtian(the seat's linked user asGET /useranswers it; always the card's assignee)Branch:
claude/issue-24022-datasource-admin-no-serverWorktree:
objectstack-issue-24022Domain:
domain:cliSeat:
domain:cli#1(seat post #6024)File surface (read on
origin/main5c2ac83a23; line numbers move; stop on a breach and explain it in the report):packages/cli/src/commands/serve.ts: thecom.objectstack.cli.datasource-admin-routesplugin'sinit(about:5111-:5135) only, and its reading ofhttp.server.packages/cli/src/**), and one.changeset/24022-*.md.readComposedHttpServer/resolveHttpServerCompositionand the banner rows (read, reused if exported in-file, not changed);publishBoundPort, theMCP:gate andholdKernelOnlyProcess(cli/serve --no-server, the remainder of #23623: theobjectstack:listeningIPC message and the runtime state file still announcehttp://localhost:PORTwith nothing listening, and a config-mounted server's banner names an unmounted MCP route #23743's and 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's, landed);registerDatasourceAdminRoutesand the routes themselves; the kernel'sgetService(packages/core).Container & model:
S(one plugin's server read on one boot shape, measured at the door with a composed control),mode:subagent,model: TIER_DEFAULT(dispatch-gates --tier: no path-derived mandate)Clause-②: no
Basis for the Clause-② line: a boot-diagnostic log line only; the routes mount on a composed boot exactly as before, and no export, flag, route or
packages/speckey changes.Responsibility:
packages/cli'sos serve, platform code in this lane | the plugin's?./??chain was written for agetServicethat returnsundefined, andgetServicethrows on an unregistered name (documented in the same file besidereadComposedHttpServer) | an operator reading a--no-serverboot's diagnostics, told to look for an ordering fault that does not exist (measured at the door by 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's dev,6222472811,out_of_scope_findings[0])Thread-read: 6223651156
Serial constraints cleared:
pm:dispatchedclaim declaresserve.tsor the datasource-admin plugin (the 22 claims read in this act), and no open PR editsserve.ts. This seat's 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 released it (bb14934cda).os startwith an uncreatableOS_HOMEhangs in Node's recursivemkdirSync(176,004 failing calls in 20 s) — the family-closing card for the remaining recursive-mkdir sites after #23696 and #23737 #23858 (p2,pm:queue, seat 2's family-closing card) namesserve.ts:978(a recursivemkdirSyncsite) among its sites. That region is disjoint from this card's plugininit; whichever lands second mergesmain.Generated by Claude Code
objectstack-fleet commentedon Oct 17, 2026
Claim: PM loop round 1 (takeover of #24022: a boot that composes no HTTP server stops printing "[datasource-admin] route registration failed: … a composition/ordering fault", and takes the plugin's own degrade line) · 2026-10-17T01:46Z
Session:
session_01BVm1pAXVXQ3PjC42j1kPFfAccount:
os-sales(the seat's linked user asGET /useranswers it; the card's assignee from this act)Branch:
claude/issue-24022-datasource-admin-no-serverWorktree:
objectstack-issue-24022Domain:
domain:cliSeat:
domain:cli#1(seat post #6024, takeover marker6228090725)Release: claim
6225067779· sessionsession_01PFB9ZGRWYvjhTXsd8i6KBp· accountmarchtian· 因: the claimant is unreachable (its session has ended, per the maintainer's confirmation in6228090725) · 去向: this claim, same branch, same file surface · 出处: the maintainer, in sessionsession_01BVm1pAXVXQ3PjC42j1kPFf's chat, verbatim 「24022 你也接手。」Resume-from:
claude/issue-24022-datasource-admin-no-server@4b0a631575da00dde1f5b03dc527dac18f4babaeHandover record: the released claim's dev pushed five commits by 2026-10-16T22:32Z, the last
4b0a631575. They are7177b4e8c(the fix in the plugin'sinitinserve.ts),2e52e010a(a newserve-datasource-admin-routes.test.tsand cases inserve-no-server-banner.integration.test.ts),acd285a2b(.changeset/24022-datasource-admin-no-server.md),16be28cdd(scripts/slot-lookup-baseline.json,serve.tsratcheted 9 → 7), and4b0a631575(a merge oforigin/main). No PR was opened and noos-dev-reportwas posted, so all of it is UNVERIFIED and is re-run in full.origin/mainis nowd6bd98a3f; since the branch's last merge it gained570c7a2d9(#24088,Fixes #23858), which editsserve.ts's runtime state file write.git merge-treereads the merge as clean.File surface (unchanged from
6225067779, plus the derived ratchet file the dev touched; re-read onorigin/maind6bd98a3f; stop on a breach and explain it in the report):packages/cli/src/commands/serve.ts: thecom.objectstack.cli.datasource-admin-routesplugin'sinitonly, and its reading ofhttp.server.packages/cli/src/commands/serve-datasource-admin-routes.test.ts(on the branch) and the cases on the branch inpackages/cli/src/commands/serve-no-server-banner.integration.test.ts; one.changeset/24022-*.md(on the branch).scripts/slot-lookup-baseline.json: derived; onlyserve.ts's row, and only downward.readComposedHttpServer/resolveHttpServerCompositionand the banner rows (read, reused if exported in-file, not changed);publishBoundPort, theMCP:gate,holdKernelOnlyProcessand the runtime state file write (cli/serve --no-server, the remainder of #23623: theobjectstack:listeningIPC message and the runtime state file still announcehttp://localhost:PORTwith nothing listening, and a config-mounted server's banner names an unmounted MCP route #23743's, 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's and fix(cli): os serve no longer hangs on a runtime state file directory that can never be made #24088's, landed);registerDatasourceAdminRoutesand the routes themselves; the kernel'sgetService(packages/core).Container & model:
S(one plugin's server read on one boot shape, continued from a pushed branch),mode:subagent,model: TIER_DEFAULT(dispatch-gates --tieron this surface: no path-derived mandate)Clause-②: no
Basis for the Clause-② line: a boot-diagnostic log line only; the routes mount on a composed boot exactly as before, and no export, flag, route or
packages/speckey changes.Responsibility:
packages/cli'sos serve, platform code in this lane | the plugin's?./??chain was written for agetServicethat returnsundefined, andgetServicethrows on an unregistered name (documented in the same file besidereadComposedHttpServer) | an operator reading a--no-serverboot's diagnostics, told to look for an ordering fault that does not exist (measured at the door by 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's dev,6222472811,out_of_scope_findings[0])Thread-read: 6225067779
Serial constraints cleared: the 10 open PRs read in this act; none edits
packages/cli/(fix(rest): the API-exposure gate reads the one object it checks, by name, instead of every object's metadata on each /data request #24093 and refactor(rest): move registerFormEndpoints into form-routes.ts (#23050 slice 11) #24054 editpackages/rest/, and fix(rest): the API-exposure gate reads the one object it checks, by name, instead of every object's metadata on each /data request #24093 onepackages/runtimetest). The two other openpm:dispatchedlane claims, rest: every /data request's API-exposure gate reads EVERY object's metadata (with a full schema diagnostic) to check ONE object's enable flags — 62-72% of a data request's time, measured #24031 (6225541511) and [maintainer] refactor(rest): splitpackages/rest/src/rest-server.ts(13,701 lines, 70 commits in 30 days) along itsregister*Endpointsseams, one move-only slice per PR,/metaafter #22877 stage 2 #23050 (6222884615), declarepackages/rest/only.serve.ts's other recent lander, fix(cli): os serve no longer hangs on a runtime state file directory that can never be made #24088, is merged.Note for triage:
findingis still on this card after the first grade6223651156. The label is triage's to clear.objectstack-fleet commentedon Oct 17, 2026
os-dev-report
{
"issue": 24022,
"status": "done",
"branch": "claude/issue-24022-datasource-admin-no-server",
"pr": "#24132",
"session": "session_01BVm1pAXVXQ3PjC42j1kPFf — subagent run, so this is the parent PM session's id (dispatch claim 6228120195)",
"premise_still_valid": true,
"summary": "RESUME of claude/issue-24022-datasource-admin-no-server@4b0a631575, newest Claim 6228120195 names this branch (checked). The worktree was built from origin/BRANCH and merged origin/main 50ccfa6 (merge b794db1, clean, no os-regen deferral). Every handover commit was read hunk by hunk. Kept: 7177b4e (the fix; the new unit file landed in THIS commit, not in 2e52e01 as the handover record says), 2e52e01 (integration cases) and 16be28c (slot-lookup serve.ts 9 to 7, re-measured after the merge, check:slot-lookup holds). Corrected: acd285a's changeset alias sentence; it now says the http-server fallback never ran. Added: commit a12bf2f, a shape 4 control backing the changeset's claim that the routes mount on a config-mounted HonoServerPlugin under --no-server. The fix: the datasource-admin plugin moves from inline in run() to an exported factory createDatasourceAdminRoutesPlugin in serve.ts (same name, version, optionalDependencies). Its init reads the server through the existing readComposedHttpServer (reused, unchanged), so a boot without a server takes the degrade line, and a registration that throws on a composed boot still warns. PM mechanism assumptions, all 3 MEASURED TRUE. (1) ctx.getService throws '[Kernel] Service ... not found' plus the describeInitOrderFault suffix (packages/core/src/kernel.ts, plugin-order.ts); the unit premise case pins it on a real ObjectKernel. (2) The ablation reproduces the card's exact WARN line at the door through the built CLI. (3) #24088's serve.ts hunks sit at about :11 and :1094; this diff sits at about :5110 and :5771. files_changed vs origin/main 50ccfa6 (5 files, +287/-35): packages/cli/src/commands/serve.ts; packages/cli/src/commands/serve-datasource-admin-routes.test.ts (new); packages/cli/src/commands/serve-no-server-banner.integration.test.ts; .changeset/24022-datasource-admin-no-server.md (cli patch); scripts/slot-lookup-baseline.json (serve.ts row only, 9 to 7). File surface: no breach. The factory extraction is the same plugin in the same file, relocated beside createUnknownHostnameGuardPlugin; no hold-off symbol was edited. line_budget: n/a (no skills/** touched). labels: 0 written; the dispatch named none, and skip-changeset does not apply. deviations: (a) fetched the teardown self-test's pinned fixture commit 621a487 with --depth=1, which adds an object and a shallow root to the shared .git; (b) origin/main moved to c1c0a90 after the merge (3 commits, packages/rest, plugin-email, qa/dogfood, runtime test, spec/liveness; none under packages/cli); merge-tree clean, NOT merged; (c) the first git push was an up-to-date no-op, so the write route was first proven by the merge push; (d) test:repo not run locally (CI's), and check:dev-prereqs and check:skill-frame-freshness not run (no packages/spec or four-axis framework file in the diff); (e) the PR body was written once at pr_create and never patched. Cleanup done: worktree node_modules removed, git worktree remove without --force exited 0, no server left running.",
"tests": "All at head a12bf2f; every exit was captured before any pipe and read from the os-verify-lock VERDICT line. (1) Unit tier: pnpm --filter @objectstack/cli exec vitest run --project unit --maxWorkers=2. 'Test Files 309 passed (309) / Tests 4588 passed (4588)', VERDICT command-exit 0. (2) New unit file, src/commands/serve-datasource-admin-routes.test.ts: 'Tests 6 passed (6)', exit 0; import 18.80s, tests 14ms on a shared box. A sibling serve importer (serve-unknown-hostname-guard.test.ts) measured the same, 36.64s of import for the two files together. (3) Integration tier, run on the touched file only, as the dispatch requires: pnpm --filter @objectstack/cli exec vitest run --project integration --maxWorkers=2 src/commands/serve-no-server-banner.integration.test.ts. 'Tests 4 passed (4)', tests 12.68s, exit 0, against the built CLI (turbo build --filter=@objectstack/cli, 61 tasks, exit 0). Other integration-tier files are declared to CI. (4) pnpm --filter @objectstack/cli typecheck: TYPECHECK_EXIT=0, including 'check:test-typecheck: OK'. tsc --noEmit --listFiles names both touched test files (count 2). (5) Ablation, once, on the changed behaviour; fix committed first. scripts/ablation-replace.mjs put the pre-fix read back (throwing getService chain inside the try): anchor x1 to x0, blob a48fc3da93e4 to 95b1a98c5f93. The CLI was rebuilt (BUILD_EXIT=0), and ablation-dist-preflight @objectstack/cli 'readComposedHttpServer(ctx)' --absent passed (PREFLIGHT_EXIT=0; dist old-chain count 2). Unit file: 'Tests 1 failed | 5 passed', failing 'takes its own degrade line'. Integration file: 'Tests 2 failed | 2 passed'; shapes 1 and 2 failed, each printing the card's 'WARN [datasource-admin] route registration failed: [Kernel] Service 'http.server' not found (while plugin 'com.objectstack.cli.datasource-admin-routes' was initializing — a composition/ordering fault; ...)'; both controls green. Direction as predicted. Restore: blob == HEAD a48fc3da93e4, git diff HEAD empty, git status --porcelain empty. Rebuilt, preflight found the marker present (PREFLIGHT_EXIT=0), unit 6/6 and integration 4/4, exits 0. Unit case 3 (only http.server asked) stays green under the mutation. It guards against an alias read coming back, not against this card's defect. (6) Door, built CLI, host fixture: 'os serve objectstack.config.ts --no-server --preset minimal' printed 'WARN [datasource-admin] http.server unavailable; REST routes not installed' and no ordering fault.",
"gates": "Local subset at head a12bf2f. Derived with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no paths; stderr: tree objectstack-ai/objectstack at the branch head, 5 paths vs merge base 50ccfa6): 75 commands, each run with its exit recorded before any pipe. 72 exited 0 on the first pass. 3 exited 3 (PREREQUISITE NOT MET) and exited 0 once the prerequisite was met: check-plugin-teardown-shape --self-test (fixture commit unreachable on the shallow clone; fetched --depth=1, then '48 cases pass'), pnpm check:dual-build-cjs-loads and pnpm check:i18n-coverage (missing dists; full turbo build, then 'OK (14 config(s), 621 baselined untranslated string(s), none new)'). dispatch-gates --ran: 'Run reconciliation — 75 derived, 75 run, 0 NOT-MEASURED, 0 UNRUN', RAN_EXIT=0. Key verdict lines: check:slot-lookup 'slot-lookup ratchet holds: 102 unswept site(s) in 25 file(s), none new'; check:test-source-alias OK; check:cross-package-test-inputs OK; check-empty-changeset 1 declaring changeset added. Lint blind spot: pnpm exec eslint --no-inline-config on the 3 changed .ts files, EXIT=0 with no output; the .md and .json are outside eslint's configured set (0 errors, 2 'File ignored' warnings). Extra, outside the derived set: pnpm check:startup-registry-verdict EXIT=0 ('45 startup/open-registry seam(s) ... none recording a verdict the boot can contradict'); node scripts/check-nul-bytes.mjs EXIT=0; manual control-byte grep over the 5 files, 0 hits. CI on PR 24132 head a12bf2f, read once and not waited on. completed/success: Governed Surface Queue Guard, Check Changeset, The card this PR closes must claim this branch, Part-of PR must not also close its card, No other open PR may claim the same issue, No other open PR may claim the same single-writer path, Check PR Size, Check Documentation Links, Flag docs affected by code changes, filter, Auto Label, Dogfood Regression Gate. in_progress: Build Core; Test Core (1/6 to 6/6); Type Check · workspace / source gates / consumer gates / debt ledger; Lint · ESLint / repo & tooling gates / docs & code guards / CI, release & engine gates / PM dispatch-gates / scoped · tooling self-tests / scoped · slot lookup & corpus / scoped · query-options erasure. skipped: Packed-tarball smoke (opt-in), Console Pin Gate, Temporal Conformance, Build Docs, Dogfood Verify CLI, Dogfood Regression Gate shards.",
"mcp_calls": "0 — no MCP GitHub tool was called",
"api_writes": "5 REST writes in 2 relay strokes: 2 seat-side POST /repos/objectstack-ai/objectstack/dispatches, and 3 writes the fleet-write relay executed as objectstack-fleet[bot]. Stroke 1 (pr_create, run 38994916698, success): POST /repos/objectstack-ai/objectstack/pulls (draft) + POST /repos//issues/24132/assignees (os-sales); read-back: 8486 bytes sent, 8486 stored, identical. Stroke 2 (this comment): POST /repos//issues/24022/comments. Not REST: 3 git push (no-op probe, merge b794db1, a12bf2f). 0 label writes. 0 PATCH.",
"open_questions": [],
"out_of_scope_findings": [
"class: a · reach: public door, built CLI at a12bf2f with a host fixture: 'OS_ROOT_DOMAIN=example.test os serve objectstack.config.ts --no-server --preset minimal' prints 'WARN [unknown-hostname-guard] install failed {"error":"[Kernel] Service 'http.server' not found (while plugin 'com.objectstack.cli.unknown-hostname-guard' was initializing — a composition/ordering fault; registration order is not a contract.)"}' when nothing is at fault · evidence: packages/cli/src/commands/serve.ts createUnknownHostnameGuardPlugin init (about :5956) reads ctx.getService?.('http.server') ?? ctx.getService?.('http-server') inside its try, and its catch (about :6121) warns 'install failed'. It is this card's defect class in the sibling plugin, and its own degrade line '[unknown-hostname-guard] http.server unavailable; guard not installed' is just as unreachable. Landing: that plugin's init in serve.ts (domain:cli); the shape is readComposedHttpServer, with a --no-server pin in serve-unknown-hostname-guard.test.ts. Not fixed in place: outside this claim's declared file surface (the datasource-admin plugin's init only), which only the seat can amend · dedupe words: unknown-hostname-guard install failed no-server; OS_ROOT_DOMAIN ordering fault http.server not found; hostname guard getService throws optional chain"
]
}
objectstack-fleet commentedon Oct 17, 2026
File surface amendment to claim
6228120195(same round, the bounded in-place fix) ·domain:cliseat 1 · sessionsession_01BVm1pAXVXQ3PjC42j1kPFf· 2026-10-17T02:32Z⛔ Not a new claim; the branch, account and seat are unchanged.
packages/cli/src/commands/serve.ts,createUnknownHostnameGuardPlugin'sinit, its read ofhttp.serveronly; its pins inpackages/cli/src/commands/serve-unknown-hostname-guard.test.ts; and the same.changeset/24022-datasource-admin-no-server.md.OS_ROOT_DOMAIN=example.test os serve objectstack.config.ts --no-server --preset minimalprintsWARN [unknown-hostname-guard] install failed {"error":"[Kernel] Service 'http.server' not found (while plugin 'com.objectstack.cli.unknown-hostname-guard' was initializing — a composition/ordering fault; …)"}. Its own degrade line,[unknown-hostname-guard] http.server unavailable; guard not installed, is just as unreachable.origin/mainc1c0a9094:git grep -nE "getService\?\.\(\s*['\"]http[.-]server['\"]\s*\)\s*\?\?"over non-testpackages/**/*.tsgives 3 hits. One isreadComposedHttpServeritself (serve.ts:550, inside itstry). The other two areserve.ts:5127(this card's plugin, fixed by PR fix(cli): a --no-server boot takes the datasource admin routes' own degrade line, not an ordering fault #24132) andserve.ts:5928(the guard). The radius is that single-line spelling. The one other alias read,cloud-connection-plugin.ts:157, is already inside atryand is outside this defect class.readComposedHttpServer); no other claim holdsserve.ts; the same gate families. After this, no member of the family is left.objectstack-fleet commentedon Oct 17, 2026
os-dev-report
{
"issue": 24022,
"status": "done",
"branch": "claude/issue-24022-datasource-admin-no-server",
"pr": "#24132",
"session": "session_01BVm1pAXVXQ3PjC42j1kPFf — subagent run, so this is the parent PM session's id (dispatch claim 6228120195, file surface amendment 6228552643)",
"premise_still_valid": true,
"summary": "PATCH ROUND 1. The newest Claim is still 6228120195, naming this branch, and amendment 6228552643 was read first. The worktree was recreated from origin/BRANCH at a12bf2f. Main (c1c0a90) was NOT merged: there was no conflict and no main-caused red, and none of it touches packages/cli. New commit 6c33626 (pushed): createUnknownHostnameGuardPlugin's init now reads the server through readComposedHttpServer. It is a one-line hunk; the read stays inside the existing try, which readComposedHttpServer never throws out of; readComposedHttpServer itself is unchanged. A no-server boot now takes '[unknown-hostname-guard] http.server unavailable; guard not installed', and an install that throws on a composed server still warns 'install failed'. Pins in serve-unknown-hostname-guard.test.ts. Changeset amended: still one @objectstack/cli patch, now naming the guard's line too. slot-lookup: serve.ts 7 to 6, only that row. Family radius on 6c33626: the seat's grep (getService?.('http[.-]server') ??, non-test packages/**/*.ts) now hits only readComposedHttpServer itself (serve.ts:550, inside its try). files_changed vs origin/main 50ccfa6 (6 files, +404/-42): packages/cli/src/commands/serve.ts; packages/cli/src/commands/serve-datasource-admin-routes.test.ts; packages/cli/src/commands/serve-no-server-banner.integration.test.ts; packages/cli/src/commands/serve-unknown-hostname-guard.test.ts; .changeset/24022-datasource-admin-no-server.md; scripts/slot-lookup-baseline.json. This round's diff (a12bf2f..6c33626): serve.ts 1 line, the guard test file +118/-6, the changeset, and the baseline row. File surface: within the amended surface. line_budget: n/a. labels: 0 written. Restart: the container restart cut the derived gate loop at 67/75, all 67 exit 0. Commands 68-75 were re-run in the foreground on 6c33626 and appended to the same record. Every other step had finished before the restart, with its verdict line recorded at 6c33626: unit tier, typecheck, eslint, integration file, both ablation legs, door. They were not re-run. deviations: (a) the derivation warns STALE TREE: 6c33626 is 3 commits behind origin/main, and 3 family files changed there (scripts/check-route-envelope.mjs, scripts/engine-double-contract.pinned.json, scripts/adr-anchors/packages__rest__src__form-routes.ts.json). Their families ran the branch's copies, kept that way per the order not to merge; CI's merge-ref run reads main's copies. (b) The guard ablation was not rebuilt, because its subject is imported from src via the relative ./serve.js. (c) A fresh worktree has no dist: the first guard test run failed to resolve @objectstack/core (a prerequisite, not a measurement); a full turbo build (71/76 cached) fixed it before every reading. (d) The PR body was NOT patched; the exact edits are in pr_body_edits. Cleanup done: door fixtures deleted, worktree node_modules removed, git worktree remove without --force exited 0, no server or watcher left running. PR body edits for the seat, also in pr_body_edits: [The fix] replace the intro line, insert one bullet after the alias bullet, and replace the slot-lookup bullet. [Pins] append one bullet after the integration bullet. [Acceptance notes] drop the line that opens '- The same defect is in the sibling plugin in this file, the unknown-hostname guard.' Recommended, not ordered: replace the '## Verification, all at head a12bf2f' section with verification_replace and add abl2_add after the round-1 ablation subsection, since the round-1 numbers name the old head.",
"tests": "All at head 6c33626; every exit was captured before any pipe and read from the os-verify-lock VERDICT line. (1) Unit tier: pnpm --filter @objectstack/cli exec vitest run --project unit --maxWorkers=2. 'Test Files 309 passed (309) / Tests 4591 passed (4591)', VERDICT command-exit 0 (4588 in round 1, +3 cases). (2) Guard file plus datasource file: 'Test Files 2 passed (2) / Tests 44 passed (44)', exit 0; the guard file alone is 38 of 38. (3) Integration file, re-run on the final head with a CLI built from it: 'Tests 4 passed (4)', exit 0. (4) pnpm --filter @objectstack/cli typecheck, joined with tsc --noEmit --listFiles by &&: VERDICT command-exit 0, 'check:test-typecheck: OK'. listFiles names all 3 touched test files. (5) Ablation, round 2, on the guard; fix committed first. scripts/ablation-replace.mjs: anchor x1 to x0, blob a080f01a90c5 to a48fc3da93e4 (byte-identical to the a12bf2f serve.ts, so the mutation is exactly the pre-fix line). Mutated: 'Tests 2 failed | 36 passed (38)', UNIT_EXIT=1. The failures are 'no server composed: the degrade line, once' (it received '[unknown-hostname-guard] install failed {"error":"[Kernel] Service 'http.server' not found (while plugin 'com.objectstack.cli.unknown-hostname-guard' was initializing — a composition/ordering fault; registration order is not a contract.)"}') and the throwing-resolution case. Both controls stayed green; direction as predicted. Restore: blob == HEAD a080f01a90c5, git diff HEAD empty, git status --porcelain empty, 38/38, UNIT_EXIT=0. (6) Door, built CLI carrying both fixes (dist old-chain count 0, readComposedHttpServer(ctx) count 2), OS_ROOT_DOMAIN=example.test. '--no-server --preset minimal' printed 'WARN [unknown-hostname-guard] http.server unavailable; guard not installed' and 'WARN [datasource-admin] http.server unavailable; REST routes not installed', no ordering fault. A default boot (OS_LOG_LEVEL=info) and a '--no-server --preset minimal' boot with a config-mounted HonoServerPlugin each logged 'INFO [unknown-hostname-guard] installed {"rootDomain":"example.test"}' and no guard warning. This backs the changeset's 'installs the hostname guard as before, including under --no-server when the config mounts its own HonoServerPlugin'. Round-1 readings (a12bf2f: datasource ablation, 4588 tests) stay in the first os-dev-report, 6228522842.",
"gates": "Local subset at head 6c33626. node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no paths; stderr: tree objectstack-ai/objectstack at commit 6c33626, 6 paths vs merge base 50ccfa6, plus the STALE TREE warning in summary deviation (a)) derives 75 commands, the same set as round 1. All 75 exit 0: 67 before the restart, 68-75 re-run in the foreground after it. dispatch-gates --ran: 'Run reconciliation — 75 derived, 75 run, 0 NOT-MEASURED, 0 UNRUN', RAN_EXIT=0. Key lines: check:slot-lookup 'slot-lookup ratchet holds: 101 unswept site(s) in 25 file(s), none new'; check:route-envelope green; check:engine-double-contract 'OK — 1017 pinned'. eslint --no-inline-config on the 4 changed .ts files: ESLINT_EXIT=0, no output. Extra: pnpm check:startup-registry-verdict EXIT=0 ('44 startup/open-registry seam(s) ... none recording a verdict the boot can contradict'); manual control-byte grep over the 6 files, 0 hits. CI on PR 24132 head 6c33626, read once and not waited on. success (32): Lint & Repo Gates, TypeScript Type Check, Build Core, Governed Surface Queue Guard, Check Changeset, Test Core 1/6, 2/6, 4/6, 5/6 and 6/6, all Lint · and Type Check · lanes, Dogfood Regression Gate, Check PR Size, Check Documentation Links, Flag docs affected by code changes, the three claim/closing guards, the two single-writer guards, Auto Label, filter. in_progress: Test Core (3/6). skipped: Build Docs, Console Pin Gate, Dogfood shards, Dogfood Verify CLI, Packed-tarball smoke, Temporal Conformance.",
"mcp_calls": "0 — no MCP GitHub tool was called",
"api_writes": "This round: 2 REST writes in 1 relay stroke, a seat-side POST /repos/objectstack-ai/objectstack/dispatches and the relay's POST /repos//issues/24022/comments (this report). Not REST: 1 git push (a12bf2f..6c33626). 0 PATCH (PR body untouched), 0 label writes. Round 1's 5 REST writes are in report 6228522842.",
"open_questions": [],
"out_of_scope_findings": [],
"pr_body_edits": {
"fix_intro_replace": {
"old": "
packages/cli/src/commands/serve.tsonly, thecom.objectstack.cli.datasource-admin-routesplugin:","new": "
packages/cli/src/commands/serve.tsonly, in two plugins:com.objectstack.cli.datasource-admin-routes, and its siblingcom.objectstack.cli.unknown-hostname-guard:"},
"fix_insert_after_alias_bullet": "- The unknown-hostname guard (
createUnknownHostnameGuardPlugin, composed whenOS_ROOT_DOMAINis set) had the same trap, so itsinitnow reads the server throughreadComposedHttpServertoo. It is a one-line hunk. The read stays inside the existingtry, andreadComposedHttpServernever throws. With no server, the boot now takes[unknown-hostname-guard] http.server unavailable; guard not installed. On a composed server whose install throws, it still warnsinstall failedwith the error. The claim's file surface was widened for this in comment6228552643.","fix_slot_lookup_replace": {
"old": "-
scripts/slot-lookup-baseline.json:serve.ts9 to 7, because the untyped two-lookup chain is gone (check:slot-lookupholds at 102 sites in 25 files).","new": "-
scripts/slot-lookup-baseline.json:serve.ts9 to 6, because both untyped two-lookup chains are gone (check:slot-lookupholds at 101 sites in 25 files)."},
"pins_append_after_integration_bullet": "-
packages/cli/src/commands/serve-unknown-hostname-guard.test.ts(unit tier, the guard's existing file):\n 1. a realObjectKernelboot with no server: noinstall failed, noordering fault, and exactly one[unknown-hostname-guard]line, the degrade line;\n 2. CONTROL: a real kernel boot with a composed server, ordered ahead byoptionalDependencies, logsinstalled, prints no[unknown-hostname-guard]warning, and refuses an unmapped host with 404ENVIRONMENT_NOT_FOUND;\n 3. CONTROL: a usable server whose raw app refuses the middleware still warnsinstall failed, naming the error;\n 4. the existing throwing service-resolution case now expects the degrade line instead ofinstall failed. The kernel throws on an unregistered name, so a throwing read IS the no-server boot.","acceptance_notes_drop": "- The same defect is in the sibling plugin in this file, the unknown-hostname guard. Its
initreadshttp.serverthrough the same throwing chain. Measured at the door:OS_ROOT_DOMAIN=example.test os serve objectstack.config.ts --no-server --preset minimalprintsWARN [unknown-hostname-guard] install failed {\"error\":\"[Kernel] Service 'http.server' not found (while plugin 'com.objectstack.cli.unknown-hostname-guard' was initializing — a composition/ordering fault; ...)\"}. It is outside this claim's file surface, so it is not changed here. It goes to the seat as a finding.","verification_replace_recommended": "## Verification, all at head
6c33626a8\n\n- Unit tier:pnpm --filter @objectstack/cli exec vitest run --project unit --maxWorkers=2reads 309 files, 4591 tests, all passed, exit 0.\n- Integration, the touched file:pnpm --filter @objectstack/cli exec vitest run --project integration --maxWorkers=2 src/commands/serve-no-server-banner.integration.test.tsreads 4 of 4 passed, exit 0. The other integration-tier files are declared to CI.\n-pnpm --filter @objectstack/cli typecheckexits 0,check:test-typecheckincluded.tsc --noEmit --listFilescompiles all three touched test files.\n-pnpm exec eslint --no-inline-configon the four changed.tsfiles exits 0 with no output. The.mdand.jsonfiles are outside eslint's configured file set.\n- Gates:node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderives 75 commands on6c33626a8, and all 75 exit 0.--ranreads75 derived, 75 run, 0 NOT-MEASURED, 0 UNRUN.\n - The derivation warns that the tree is 3 commits behindorigin/mainc1c0a9094, where 3 family files changed:check-route-envelope.mjs,engine-double-contract.pinned.jsonand onescripts/adr-anchorsfile. Those families ran the branch's copies. CI's merge-ref run is the reading on main's copies.\n - Also run, outside the derived set:check:startup-registry-verdict(exit 0, 44 seams, none recording a verdict the boot can contradict).\n- At the door, against the built CLI, withOS_ROOT_DOMAIN=example.test:\n -os serve objectstack.config.ts --no-server --preset minimalprintsWARN [unknown-hostname-guard] http.server unavailable; guard not installedandWARN [datasource-admin] http.server unavailable; REST routes not installed, and no ordering fault;\n - a default boot, and a--no-serverboot whose config mounts its ownHonoServerPlugin, each logINFO [unknown-hostname-guard] installed, with no guard warning.","ablation_round2_append_recommended": "### Ablation, round 2 (the guard)\n\nThe fix was committed first (
6c33626a8).scripts/ablation-replace.mjsput the guard's pre-fix line back. The anchor count went from 1 to 0, and the blob went froma080f01a90c5toa48fc3da93e4, which is byte-identical to the previous head'sserve.ts. The test imports its subject from source (./serve.js), so no rebuild sits in the path.\n\n- Mutated leg: the guard file reads 2 failed, 36 passed. Both failures are the cases that read a throwing service as no server: the real-kernel no-server boot, which received the exact[unknown-hostname-guard] install failed ... a composition/ordering faultline, and the throwing-resolution case. Both controls stayed green.\n- Restore leg: blob back to the HEAD blob,git diff HEADempty,git status --porcelainempty. 38 of 38 passed."}
}
objectstack-fleet commentedon Oct 17, 2026
ACCEPT → PR #24132 comment 6228868889 · head
6c33626a8·domain:cliseat 1 · sessionsession_01BVm1pAXVXQ3PjC42j1kPFf· 2026-10-17T03:08Zobjectstack-fleet commentedon Oct 17, 2026
Landed: PR #24132 ·
domain:cliseat 1 · sessionsession_01BVm1pAXVXQ3PjC42j1kPFf· 2026-10-17T03:33Zorigin/main27d7c2aa1"fix(cli): a --no-server boot takes the datasource admin routes' own degrade line, not an ordering fault (#24132)";git rev-list --parents -n1gives 1 parent, a squashgit ls-remote origin 'refs/heads/gh-readonly-queue/main/pr-24132-*'gives 0 refsmerged: trueat 2026-10-17T03:32:35Zdomain:cliset lost #24022 only, so no other card was closed by a keywordState: closed
completedbyFixes #24022;pm:dispatchedstripped in this act. Both members of the family, the datasource admin routes and the unknown-hostname guard, are onmain.For triage:
findingis still on this closed card. It is triage's label.