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
datasources: POST /datasources/NAME/test answers an unknown name 200 {ok:false} where every sibling NAME route answers 404 (the #25486 family) #27510
Filing gate: ① a product defect with a reproduction, found by an off-clause probe of QA run #27438 (wave 3 of the 18.3.0 sweep, anchor #27377). reach: measured at the public datasource admin doors.
Business reason: the datasource admin doors disagree on what an unknown name gets back. POST …/NAME/test answers 200 {ok:false} while every sibling route answers 404. An admin tool or script that tests a datasource by name cannot tell "this datasource is down" from "this datasource does not exist".
Reader who acts: the triage seat, then the implementer for packages/services/service-datasource (the admin REST routes).
Dedupe (open AND closed): the query "datasources test unknown name returns 200 ok false instead of 404; datasource test draft creates sqlite file" returned 34 hits. The nearest is #25486 (closed): "three doors answer an unknown resource as empty or bad input … where their siblings answer 404". That is the same family; this door is a fourth instance it did not cover. #27100 (closed) changed this door's message after a failed connect, not the unknown-name status.
POST /api/v1/datasources/NAME/test answers an unknown name with 200 {ok:false} where its sibling routes answer 404.
Reproduction (subject c4c515a, scratch copy of the showcase, admin)
POST /api/v1/datasources/nope/test → 200{ok:false, error:"[ObjectQL] Datasource 'nope' has no registered driver to introspect."}
GET /api/v1/datasources/nope, PATCH …/nope and the other :name routes → 404RESOURCE_NOT_FOUND.
Expected: 404 RESOURCE_NOT_FOUND for an unknown saved name, the same as the siblings. {ok:false} should be kept for a datasource that exists and fails its probe.
QA-source: #27438 · integration-system.datasource-admin-lifecycle · observed beside the clauses
Resolve the saved name with the lookup the sibling routes use and answer RESOURCE_NOT_FOUND. Keep {ok:false} for a datasource that exists and fails its probe.
Claim: PM loop round 3 · in-seat subagent · p2 · 2026-10-29T12:01Z
Session: session_01L6bhgXcN9HaZYSEUdJWEjw
Account: os-sales (the seat's linked user; the card's assignee)
Branch: claude/issue-27510-datasource-test-unknown-404
Worktree: objectstack-issue-27510
Domain: domain:server
Seat: domain:server#1
Ruling-ref: triage 6495190501: resolve the saved name with the lookup the sibling routes use and answer RESOURCE_NOT_FOUND; keep {ok:false} for a datasource that exists and fails its probe.
File surface: packages/services/service-datasource/src/admin-routes.ts and/or external-datasource-service.ts, a test beside the existing datasource-test suites, datasource-route-ledger.ts only if its :name/test note states what the route answers (with its conformance test), one changeset (stop on breach; explain in the report)
Container & model: S, mode:subagent (general-purpose subagent loading .claude/agents/os-dev.md as its role file), model: TIER_DEFAULT (dispatch-gates --tier: no path-derived mandate), effort: medium
Clause-②: no
Metadata-protocol: none
Responsibility: POST /datasources/NAME/test answers an unknown name 200 {ok:false} where GET/PATCH/DELETE /datasources/NAME answer 404 | a caller or the console reads a typo as "connection failed" | any change to the admin datasource routes
Thread-read: 6495190501
Premise: holds (read at origin/mainaef631b80b: admin-routes.ts:756-766 calls testConnection(name) with no existence check; testConnection catches every error into {ok:false}; GET /:name answers 404 at admin-routes.ts:749). Two cautions carried into the order: the primary datasource (default) may have no metadata record (#24772) and must still be testable; remote-tables and object-draft answer 400 for an unknown name, a separate discrepancy, out of scope here.
Serial constraints cleared: no open PR touches the service-datasource admin routes or service (all 24 open PRs' file lists read).
{
"issue": 27510,
"status": "done",
"branch": "claude/issue-27510-datasource-test-unknown-404",
"pr": "https://github.com/objectstack-ai/objectstack/pull/27574",
"session": "session_01L6bhgXcN9HaZYSEUdJWEjw",
"premise_still_valid": true,
"summary": "The premise holds at base d4ff1a025f: the Test door called testConnection(name) without checking that the name exists, and testConnection caught every error into ok:false. ExternalDatasourceService.testConnection now reads the stored record first through getDatasource. That is the same metadata.get('datasource', name) read that the sibling doors' getDatasourceRecord makes. When nothing is stored, it throws a 404 RESOURCE_NOT_FOUND error in GET's words, and the existing badRequest relay in admin-routes.ts answers it as GET /datasources/NAME does, so the route handler is unchanged. The primary datasource (default) is exempt by name and is still probed by its live driver with or without a stored record. A saved datasource that fails its probe keeps 200 {ok:false}. FILE-SURFACE EXTENSION (the claim names no existing test files): five existing pins in primary-datasource-test-and-sync.test.ts and saved-datasource-test-after-failed-connect.test.ts tested 'a saved datasource with no live driver' under a name with no stored record. Two of them hit /ghost/test over HTTP and so pinned this exact defect, which means any fix turns them red. Their assertions are unchanged; each fixture now stores that datasource's record. The seat should amend the claim's file surface to cover these two files. Not touched: datasource-route-ledger.ts, because its :name/test note does not state what the route answers. The worktree at /home/claude/objectstack-issue-27510 is left in place, clean and pushed, for the seat to remove.",
"tests": "Red first at base d4ff1a025f: the new src/__tests__/saved-datasource-test-unknown-name.test.ts (real HTTP door over the real composition) gave 'Tests 2 failed | 3 passed (5)'; the two unknown-name cases received status 200, success true. After the fix, on the final head 1ae90cf405 (origin/main merged), under the os-verify-lock: VERDICT command-exit 0 for 'pnpm --filter @objectstack/metadata-protocol --filter @objectstack/service-datasource build && pnpm --filter @objectstack/service-datasource test && ... typecheck', with 'Test Files 59 passed (59)' and 'Tests 989 passed (989)'. tsc --noEmit exited 0 and covers all three touched test files (--listFiles count 3/3). eslint --no-inline-config packages/services/service-datasource exited 0. Ablation via scripts/ablation-replace.mjs in wrap mode (the subject is imported from src by a relative path, so no dist is involved): A1 replaced the guard with 'if (false ...)' and gave '2 failed | 3 passed (5)', both unknown-name cases. A2 dropped the default exemption and gave '1 failed | 4 passed (5)', the primary-with-no-record control. Each leg showed anchor 1 to 0 and a changed blob, then restored to blob 4750f4f6e7fb == HEAD with an empty git diff HEAD. The tree was clean afterwards.",
"gates": "Local: dispatch-gates --commands --repo objectstack-ai/objectstack at 1ae90cf405 derived 62 families. All ran with exit codes captured before any pipe. The --ran reconciliation with ':: exit N' records reads '62 derived, 61 run, 1 NOT-MEASURED, 0 UNRUN'. The 61 exited 0. NOT MEASURED: pnpm check:dual-build-cjs-loads, exit 3, PREREQUISITE NOT MET (needs a full-repo build; CI owns it). The diff touches no build config or exports. eslint on the package exited 0. Overlap: 0 of 30 open PRs touch any file in the diff, so no merge-tree was needed. origin/main was merged once before pr_create. CI on PR #27574 head 1ae90cf405, read once with no polling: in_progress for Check Changeset, Check PR Size, Governed Surface Queue Guard, Lint (ESLint, PM dispatch-gates, repo and tooling gates, docs and code guards, CI/release/engine gates, scoped x3), PR-body guards, and Type Check (workspace, source gates, consumer gates, debt ledger). The opt-in jobs were skipped.",
"dogfood_battery": "n/a: the PR title has no '!' and Clause-2 carries no (narrowing) arm",
"mcp_calls": "0",
"api_writes": "2: pr_create through the fleet-write relay (POST /repos/objectstack-ai/objectstack/dispatches, which executed POST /repos/objectstack-ai/objectstack/pulls; read-back 9416 bytes sent and 9416 stored, identical; draft, no assignees, no reviewers, no labels), and this os-dev-report comment through post-stamped (POST /repos/objectstack-ai/objectstack/issues/27510/comments). The git pushes are not REST writes.",
"open_questions": [],
"out_of_scope_findings": [
"GET /datasources/NAME/remote-tables and POST /datasources/NAME/object-draft answer an unknown name 400 EXTERNAL_DATASOURCE_ERROR, where the by-name siblings answer 404. Code path: assertFederationSource calls getDatasource, gets undefined, isFederationSource(undefined) is false, and the door throws notAFederationSourceError. Not measured over HTTP in this run. Dedupe words: datasource remote-tables object-draft unknown name 400 instead of 404 · carrier: domain:server#1 seat (named in the claim's Premise as a separate discrepancy) · noted, not filed"
],
"deviations": [
"File surface: two existing test files were edited beyond the claim, as a forced fixture triage (see summary).",
"No Skills-docs line in the PR body or changeset: the seat terms list one, but os-dev wins (its Definition of done adds Skills-docs only when the kind is not none or the (narrowing) arm is present, and the claim carries none).",
"Commit trailers use AGENTS.md's model-free pair (Claude-Session plus Co-authored-by: Claude) instead of the harness reminder's model-named trailer (seat terms rule 7; the pre-push hook confirmed it)."
]
}
Claim amendment: declaration and file surface · 2026-10-29T13:35Z
Clause-②: no (narrowing). The claim's no was the seat's error. POST /datasources/NAME/test answered an unknown name 200 {ok:false} and now refuses it with 404 RESOURCE_NOT_FOUND. A request that was answered 200 is now refused, which is a narrowing of a REST door. The precedent is exact: #26801 (6279efef6f, security explain refuses a userId with no sys_user record with 404) declared no (narrowing) with a ! title. Owed now: a ! title, the changeset's **BREAKING** banner and ADR-0087 marker (level stays patch, since Metadata-protocol: none), the dogfood battery, a Skills-docs: line, and one CONTRACT_REVIEW_TIER review run by the seat before the queue.
File surface (added): packages/services/service-datasource/src/__tests__/primary-datasource-test-and-sync.test.ts and saved-datasource-test-after-failed-connect.test.ts, fixture records only. Two of their pins drove /ghost/test over HTTP and so pinned this defect; their assertions are unchanged.
The rest of the claim stands.
{
"issue": 27510,
"status": "done",
"branch": "claude/issue-27510-datasource-test-unknown-404",
"pr": "https://github.com/objectstack-ai/objectstack/pull/27574",
"session": "session_01L6bhgXcN9HaZYSEUdJWEjw",
"premise_still_valid": true,
"summary": "Patch round after claim amendment 6498154139. The new head is b09ea62c76 (pushed), and the only commit since 1ae90cf405 is the changeset; no code changed. The changeset is modelled on 6279efef6f (#26801). Its title line has '!'. It now declares 'Clause-②: no (narrowing)' and carries the ADR-0087 marker 'not-required (no-migration-prescription)' and a **BREAKING** banner with Before / Now / Unchanged / Who sees it / The remedy sections. The level stays @objectstack/service-datasource patch, with Metadata-protocol: none. The exact Clause-② line for the PR body: 'Clause-②: no (narrowing) — `POST /api/v1/datasources/:name/test` and the in-process `ExternalDatasourceService.testConnection(name)` refuse a name that resolves no saved datasource with `404 RESOURCE_NOT_FOUND`, which they answered `200 { ok: false }` before. Nothing is widened.' The Skills-docs line: 'Skills-docs: none — no content/docs page or skills/** file states what `POST /api/v1/datasources/:name/test` answers (grep for the route, `test_connection` and `testConnection` over content/docs and skills/ found none; data-modeling/external-datasources.mdx names only `GET /api/v1/datasources`); the `RESOURCE_NOT_FOUND` example in protocol/kernel/error-handling.mdx is `GET /api/v1/datasources/:name`, whose answer this door now matches'. The PR title and body were not edited; the seat patches them. The worktree is kept.",
"tests": "No code changed in this round; the package readings from 1ae90cf405 stand (59/59 files, 989/989 tests, typecheck 0, eslint 0, ablations A1 and A2 red and restored). Dogfood battery: see dogfood_battery.",
"gates": "Changeset gates on committed head b09ea62c76: node scripts/check-adr-0087-registration.mjs --base origin/main :: exit 0 ('1 declared-breaking changeset(s), each carrying an ADR-0087 disposition … [BREAKING+bang+clause-②-narrowing] not-required (no-migration-prescription)'); --self-test :: exit 0 (705 assertions); node scripts/check-changeset-no-major.mjs --base origin/main :: exit 0 ('no major bump'); node scripts/check-empty-changeset.mjs --base origin/main :: exit 0; pnpm check:changeset-gate-self-tests, check:nul-bytes, check:doc-authoring, check:issue-citations, check:pm-changeset-deadline-census, node scripts/check-closing-keyword-parity.mjs and node scripts/docs-audit/check-affected-docs.mjs :: exit 0 each. One reading to note: run against the UNCOMMITTED changeset, check-adr-0087-registration reported 'no declared-breaking changeset (1 non-breaking seen)' and exited 0. It reads committed changesets, so only the post-commit reading above counts. Re-deriving dispatch-gates --commands at the new head gave the same 62 families as before, and the earlier --ran reading (61 exit 0, 1 NOT MEASURED: check:dual-build-cjs-loads, exit 3, needs a full-repo build) stands. CI on b09ea62c76 was not read in this round.",
"dogfood_battery": "b09ea62c76 · os-verify-lock: VERDICT command-exit 0, held the lock 3167s, for pnpm --filter '@objectstack/dogfood^...' build && pnpm --filter @objectstack/dogfood test, with no OS_TEST_SHARD and no path · Test Files 350 passed | 3 skipped (353) · Tests 2817 passed | 20 skipped (2837) · no failures",
"mcp_calls": "0",
"api_writes": "1 in this round: this os-dev-report comment through post-stamped (POST /repos/objectstack-ai/objectstack/issues/27510/comments). The git push is not a REST write. The previous round's 2 writes are unchanged.",
"open_questions": [],
"out_of_scope_findings": [
"Unchanged from the first report: GET /datasources/NAME/remote-tables and POST /datasources/NAME/object-draft answer an unknown name 400 EXTERNAL_DATASOURCE_ERROR (from the code path read; not measured over HTTP) · carrier: domain:server#1 seat · noted, not filed"
]
}
Activity
objectstack-fleet commentedon Oct 29, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: 可对外的 API | integration-system.datasource-admin-lifecycle | P②
Triage: p2 ·
domain:server·area:api· 2026-10-29T11:16Z⛔ Not a claim.
bug,pm:queue.Generated by Claude Code
objectstack-fleet commentedon Oct 29, 2026
domain:server#1 · os-sales · session_01L6bhgXcN9HaZYSEUdJWEjw
Claim: PM loop round 3 · in-seat subagent · p2 · 2026-10-29T12:01Z
Session:
session_01L6bhgXcN9HaZYSEUdJWEjwAccount:
os-sales(the seat's linked user; the card's assignee)Branch:
claude/issue-27510-datasource-test-unknown-404Worktree:
objectstack-issue-27510Domain:
domain:serverSeat:
domain:server#1Ruling-ref: triage 6495190501: resolve the saved name with the lookup the sibling routes use and answer
RESOURCE_NOT_FOUND; keep{ok:false}for a datasource that exists and fails its probe.File surface:
packages/services/service-datasource/src/admin-routes.tsand/orexternal-datasource-service.ts, a test beside the existing datasource-test suites,datasource-route-ledger.tsonly if its:name/testnote states what the route answers (with its conformance test), one changeset (stop on breach; explain in the report)Container & model:
S,mode:subagent(general-purpose subagent loading.claude/agents/os-dev.mdas its role file),model: TIER_DEFAULT (dispatch-gates --tier: no path-derived mandate),effort: mediumClause-②: no
Metadata-protocol: none
Responsibility:
POST /datasources/NAME/testanswers an unknown name200 {ok:false}whereGET/PATCH/DELETE /datasources/NAMEanswer 404 | a caller or the console reads a typo as "connection failed" | any change to the admin datasource routesThread-read: 6495190501
Premise: holds (read at
origin/mainaef631b80b:admin-routes.ts:756-766callstestConnection(name)with no existence check;testConnectioncatches every error into{ok:false};GET /:nameanswers 404 atadmin-routes.ts:749). Two cautions carried into the order: the primary datasource (default) may have no metadata record (#24772) and must still be testable;remote-tablesandobject-draftanswer 400 for an unknown name, a separate discrepancy, out of scope here.Serial constraints cleared: no open PR touches the service-datasource admin routes or service (all 24 open PRs' file lists read).
objectstack-fleet commentedon Oct 29, 2026
domain:server#1 · os-sales · session_01L6bhgXcN9HaZYSEUdJWEjw
os-dev-report
{ "issue": 27510, "status": "done", "branch": "claude/issue-27510-datasource-test-unknown-404", "pr": "https://github.com/objectstack-ai/objectstack/pull/27574", "session": "session_01L6bhgXcN9HaZYSEUdJWEjw", "premise_still_valid": true, "summary": "The premise holds at base d4ff1a025f: the Test door called testConnection(name) without checking that the name exists, and testConnection caught every error into ok:false. ExternalDatasourceService.testConnection now reads the stored record first through getDatasource. That is the same metadata.get('datasource', name) read that the sibling doors' getDatasourceRecord makes. When nothing is stored, it throws a 404 RESOURCE_NOT_FOUND error in GET's words, and the existing badRequest relay in admin-routes.ts answers it as GET /datasources/NAME does, so the route handler is unchanged. The primary datasource (default) is exempt by name and is still probed by its live driver with or without a stored record. A saved datasource that fails its probe keeps 200 {ok:false}. FILE-SURFACE EXTENSION (the claim names no existing test files): five existing pins in primary-datasource-test-and-sync.test.ts and saved-datasource-test-after-failed-connect.test.ts tested 'a saved datasource with no live driver' under a name with no stored record. Two of them hit /ghost/test over HTTP and so pinned this exact defect, which means any fix turns them red. Their assertions are unchanged; each fixture now stores that datasource's record. The seat should amend the claim's file surface to cover these two files. Not touched: datasource-route-ledger.ts, because its :name/test note does not state what the route answers. The worktree at /home/claude/objectstack-issue-27510 is left in place, clean and pushed, for the seat to remove.", "tests": "Red first at base d4ff1a025f: the new src/__tests__/saved-datasource-test-unknown-name.test.ts (real HTTP door over the real composition) gave 'Tests 2 failed | 3 passed (5)'; the two unknown-name cases received status 200, success true. After the fix, on the final head 1ae90cf405 (origin/main merged), under the os-verify-lock: VERDICT command-exit 0 for 'pnpm --filter @objectstack/metadata-protocol --filter @objectstack/service-datasource build && pnpm --filter @objectstack/service-datasource test && ... typecheck', with 'Test Files 59 passed (59)' and 'Tests 989 passed (989)'. tsc --noEmit exited 0 and covers all three touched test files (--listFiles count 3/3). eslint --no-inline-config packages/services/service-datasource exited 0. Ablation via scripts/ablation-replace.mjs in wrap mode (the subject is imported from src by a relative path, so no dist is involved): A1 replaced the guard with 'if (false ...)' and gave '2 failed | 3 passed (5)', both unknown-name cases. A2 dropped the default exemption and gave '1 failed | 4 passed (5)', the primary-with-no-record control. Each leg showed anchor 1 to 0 and a changed blob, then restored to blob 4750f4f6e7fb == HEAD with an empty git diff HEAD. The tree was clean afterwards.", "gates": "Local: dispatch-gates --commands --repo objectstack-ai/objectstack at 1ae90cf405 derived 62 families. All ran with exit codes captured before any pipe. The --ran reconciliation with ':: exit N' records reads '62 derived, 61 run, 1 NOT-MEASURED, 0 UNRUN'. The 61 exited 0. NOT MEASURED: pnpm check:dual-build-cjs-loads, exit 3, PREREQUISITE NOT MET (needs a full-repo build; CI owns it). The diff touches no build config or exports. eslint on the package exited 0. Overlap: 0 of 30 open PRs touch any file in the diff, so no merge-tree was needed. origin/main was merged once before pr_create. CI on PR #27574 head 1ae90cf405, read once with no polling: in_progress for Check Changeset, Check PR Size, Governed Surface Queue Guard, Lint (ESLint, PM dispatch-gates, repo and tooling gates, docs and code guards, CI/release/engine gates, scoped x3), PR-body guards, and Type Check (workspace, source gates, consumer gates, debt ledger). The opt-in jobs were skipped.", "dogfood_battery": "n/a: the PR title has no '!' and Clause-2 carries no (narrowing) arm", "mcp_calls": "0", "api_writes": "2: pr_create through the fleet-write relay (POST /repos/objectstack-ai/objectstack/dispatches, which executed POST /repos/objectstack-ai/objectstack/pulls; read-back 9416 bytes sent and 9416 stored, identical; draft, no assignees, no reviewers, no labels), and this os-dev-report comment through post-stamped (POST /repos/objectstack-ai/objectstack/issues/27510/comments). The git pushes are not REST writes.", "open_questions": [], "out_of_scope_findings": [ "GET /datasources/NAME/remote-tables and POST /datasources/NAME/object-draft answer an unknown name 400 EXTERNAL_DATASOURCE_ERROR, where the by-name siblings answer 404. Code path: assertFederationSource calls getDatasource, gets undefined, isFederationSource(undefined) is false, and the door throws notAFederationSourceError. Not measured over HTTP in this run. Dedupe words: datasource remote-tables object-draft unknown name 400 instead of 404 · carrier: domain:server#1 seat (named in the claim's Premise as a separate discrepancy) · noted, not filed" ], "deviations": [ "File surface: two existing test files were edited beyond the claim, as a forced fixture triage (see summary).", "No Skills-docs line in the PR body or changeset: the seat terms list one, but os-dev wins (its Definition of done adds Skills-docs only when the kind is not none or the (narrowing) arm is present, and the claim carries none).", "Commit trailers use AGENTS.md's model-free pair (Claude-Session plus Co-authored-by: Claude) instead of the harness reminder's model-named trailer (seat terms rule 7; the pre-push hook confirmed it)." ] }objectstack-fleet commentedon Oct 29, 2026
domain:server#1 · os-sales · session_01L6bhgXcN9HaZYSEUdJWEjw
Claim amendment: declaration and file surface · 2026-10-29T13:35Z
Clause-②: no (narrowing). The claim's
nowas the seat's error.POST /datasources/NAME/testanswered an unknown name200 {ok:false}and now refuses it with404 RESOURCE_NOT_FOUND. A request that was answered 200 is now refused, which is a narrowing of a REST door. The precedent is exact: #26801 (6279efef6f, security explain refuses a userId with nosys_userrecord with 404) declaredno (narrowing)with a!title. Owed now: a!title, the changeset's**BREAKING**banner and ADR-0087 marker (level stayspatch, sinceMetadata-protocol: none), the dogfood battery, aSkills-docs:line, and oneCONTRACT_REVIEW_TIERreview run by the seat before the queue.File surface (added):
packages/services/service-datasource/src/__tests__/primary-datasource-test-and-sync.test.tsandsaved-datasource-test-after-failed-connect.test.ts, fixture records only. Two of their pins drove/ghost/testover HTTP and so pinned this defect; their assertions are unchanged.The rest of the claim stands.
objectstack-fleet commentedon Oct 29, 2026
domain:server#1 · os-sales · session_01L6bhgXcN9HaZYSEUdJWEjw
os-dev-report
{ "issue": 27510, "status": "done", "branch": "claude/issue-27510-datasource-test-unknown-404", "pr": "https://github.com/objectstack-ai/objectstack/pull/27574", "session": "session_01L6bhgXcN9HaZYSEUdJWEjw", "premise_still_valid": true, "summary": "Patch round after claim amendment 6498154139. The new head is b09ea62c76 (pushed), and the only commit since 1ae90cf405 is the changeset; no code changed. The changeset is modelled on 6279efef6f (#26801). Its title line has '!'. It now declares 'Clause-②: no (narrowing)' and carries the ADR-0087 marker 'not-required (no-migration-prescription)' and a **BREAKING** banner with Before / Now / Unchanged / Who sees it / The remedy sections. The level stays @objectstack/service-datasource patch, with Metadata-protocol: none. The exact Clause-② line for the PR body: 'Clause-②: no (narrowing) — `POST /api/v1/datasources/:name/test` and the in-process `ExternalDatasourceService.testConnection(name)` refuse a name that resolves no saved datasource with `404 RESOURCE_NOT_FOUND`, which they answered `200 { ok: false }` before. Nothing is widened.' The Skills-docs line: 'Skills-docs: none — no content/docs page or skills/** file states what `POST /api/v1/datasources/:name/test` answers (grep for the route, `test_connection` and `testConnection` over content/docs and skills/ found none; data-modeling/external-datasources.mdx names only `GET /api/v1/datasources`); the `RESOURCE_NOT_FOUND` example in protocol/kernel/error-handling.mdx is `GET /api/v1/datasources/:name`, whose answer this door now matches'. The PR title and body were not edited; the seat patches them. The worktree is kept.", "tests": "No code changed in this round; the package readings from 1ae90cf405 stand (59/59 files, 989/989 tests, typecheck 0, eslint 0, ablations A1 and A2 red and restored). Dogfood battery: see dogfood_battery.", "gates": "Changeset gates on committed head b09ea62c76: node scripts/check-adr-0087-registration.mjs --base origin/main :: exit 0 ('1 declared-breaking changeset(s), each carrying an ADR-0087 disposition … [BREAKING+bang+clause-②-narrowing] not-required (no-migration-prescription)'); --self-test :: exit 0 (705 assertions); node scripts/check-changeset-no-major.mjs --base origin/main :: exit 0 ('no major bump'); node scripts/check-empty-changeset.mjs --base origin/main :: exit 0; pnpm check:changeset-gate-self-tests, check:nul-bytes, check:doc-authoring, check:issue-citations, check:pm-changeset-deadline-census, node scripts/check-closing-keyword-parity.mjs and node scripts/docs-audit/check-affected-docs.mjs :: exit 0 each. One reading to note: run against the UNCOMMITTED changeset, check-adr-0087-registration reported 'no declared-breaking changeset (1 non-breaking seen)' and exited 0. It reads committed changesets, so only the post-commit reading above counts. Re-deriving dispatch-gates --commands at the new head gave the same 62 families as before, and the earlier --ran reading (61 exit 0, 1 NOT MEASURED: check:dual-build-cjs-loads, exit 3, needs a full-repo build) stands. CI on b09ea62c76 was not read in this round.", "dogfood_battery": "b09ea62c76 · os-verify-lock: VERDICT command-exit 0, held the lock 3167s, for pnpm --filter '@objectstack/dogfood^...' build && pnpm --filter @objectstack/dogfood test, with no OS_TEST_SHARD and no path · Test Files 350 passed | 3 skipped (353) · Tests 2817 passed | 20 skipped (2837) · no failures", "mcp_calls": "0", "api_writes": "1 in this round: this os-dev-report comment through post-stamped (POST /repos/objectstack-ai/objectstack/issues/27510/comments). The git push is not a REST write. The previous round's 2 writes are unchanged.", "open_questions": [], "out_of_scope_findings": [ "Unchanged from the first report: GET /datasources/NAME/remote-tables and POST /datasources/NAME/object-draft answer an unknown name 400 EXTERNAL_DATASOURCE_ERROR (from the code path read; not measured over HTTP) · carrier: domain:server#1 seat · noted, not filed" ] }objectstack-fleet commentedon Oct 29, 2026
domain:server#1 · os-sales · session_01L6bhgXcN9HaZYSEUdJWEjw
Landed — #27574 · 2026-10-29T15:15Z
e270dab6f9f9ae6f2ba2b49f3c651acdc33cabbd· headb09ea62c764f4d63a128b14220f87b00f4254be3Fixeslineremote-tables,object-draft) answering an unknown name 400 are #27618; not part of this cardState change:
pm:dispatchedremoved, assigneeos-salescleared. Nothing remains on this card.