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
service-datasource: remote-tables?schema= never narrows on the in-tree SQL drivers, so a named schema answers 200 with the wrong tables (#24619 row c) #24664
Filing gate ④: a per-lane split of roll-up #24619 (row c). That card's triage (6272616654) says to split it on pickup. domain:engine seat 1 claimed row (a) only (6277262398) and pointed rows (b) and (c) back to triage (#60156277316794). Each row is ①. Filed by the triage seat (seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U. ⛔ Not a claim. Reader who acts: the domain:services seat (packages/services/service-datasource).
Answer: 200 with the public tables, and never the sales one.
Expected: the named schema's tables, or an explicit "schema filter not supported" refusal, not a silently wrong 200.
Fresh read (origin/maincc95f5e63e)
packages/services/service-datasource/src/external-datasource-service.ts:383 skips a table only when opts?.schema && tableSchema && tableSchema !== opts.schema.
The twin test passes only because its fake returns qualified names.
The route is admin-routes.ts:703–707.
Pins:
a real-driver introspection, or a fake that answers the way the in-tree drivers do, with no schema-qualified names;
?schema= narrows the list or refuses explicitly;
the allow-list guard at :385 is judged the same way.
Dedupe
#24619's search covers this row: "external datasource remote-tables schema filter never narrows postgres unqualified table names", 19 hits, all closed. None is on the filter.
Claim: PM loop round 5 · 2026-10-19T23:08Z
Session: session_01LR1cD9JqgkeqY7k9rrZH8s
Account: os-warren (the seat's linked user as GET /user answers it; always the card's assignee)
Branch: claude/issue-24664-remote-tables-schema-filter
Worktree: objectstack-issue-24664
Domain: domain:services
Seat: domain:services#2 (seat post #21118)
File surface: packages/services/service-datasource/src/** (external-datasource-service.ts's remote-table listing, its ?schema= filter and allowedSchemas guard, and admin-routes.ts's route if the answer changes there), new or extended test files beside them; a changeset; a driver's introspection file only if declared in the report first; ⛔ not packages/spec/** (stop on breach; explain in the report)
Container & model: S, mode:subagent, model: opus (the default tier; dispatch-gates --tier printed no path-derived mandate for this surface)
Clause-②: no
Responsibility: the remote-table listing's schema filter and allow-list (this lane, service-datasource) | ?schema= narrows to the named schema or refuses explicitly, never a silently wrong 200; allowedSchemas is judged the same way (card) | admins browsing an external Postgres or SQLite datasource's tables (#24619 row c)
Thread-read: none
Serial constraints cleared: no open PR touches packages/services/service-datasource/ (a file scan of every open PR at this claim). #24619's row (a) is domain:engine seat 1's (6277262398), on another surface.
{
"issue": 24664,
"status": "done",
"branch": "claude/issue-24664-remote-tables-schema-filter",
"pr": "https://github.com/objectstack-ai/objectstack/pull/24706",
"session": "session_01LR1cD9JqgkeqY7k9rrZH8s — the harness-stamped Claude-Session id of this run (subagent, so the parent seat's id)",
"premise_still_valid": true,
"summary": "listRemoteTables now applies a schema filter in force (?schema= or the datasource's external.allowedSchemas) to every table or refuses: where the introspection names no schema for a table (the in-tree SqlDriver, every dialect, measured on live PostgreSQL 16 and SQLite) it throws 400 EXTERNAL_DATASOURCE_ERROR, which both route spellings already serve unchanged, instead of answering a 200 with tables the filter never narrowed. A producer that reports qualified names is narrowed as before (the old qualified fakes kept as the control), a filter no table can pass answers [], and an unfiltered listing is unchanged. Route (b) for every dialect: no driver file and nothing under packages/spec touched. Declared Clause-② no (narrowing) with a minor changeset, the grade the level gate asks for that arm.",
"tests": "head 118169806. NEW packages/services/service-datasource/src/__tests__/remote-tables-schema-attribution.test.ts, 12 cases: a real in-memory SqlDriver SQLite introspection (unfiltered list kept; ?schema= and allowedSchemas refused), a Postgres fake holding the measured real introspection on the default path and on searchPath sales (?schema=sales refused, which is the card's row; refused even when every table is in sales; allowedSchemas refused; unsatisfiable filter answers []; unfiltered list kept), the qualified-name control (narrows by ?schema=, by allowedSchemas, by both; one bare name among qualified refuses), and the route via real HonoHttpServer (GET /api/v1/datasources/pg/remote-tables?schema=sales answers 400, success false, error.code EXTERNAL_DATASOURCE_ERROR; without ?schema= 200 with the table). pnpm --filter @objectstack/service-datasource test: Test Files 46 passed (46), Tests 850 passed (850). pnpm --filter @objectstack/service-datasource typecheck: exit 0, and tsc --listFiles counts the new test file 1 time. pnpm --filter @objectstack/rest exec vitest run src/remote-tables-twin.equivalence.test.ts src/external-datasource-envelope.conformance.test.ts: 2 files, 26 passed (the rest vitest config aliases service-datasource to src). All three ran under os-verify-lock, VERDICT command-exit 0. ABLATION (one): node scripts/ablation-replace.mjs wrap mode, under the lock, on 0e100d3a4, anchor 'unattributed.push(table.name);' replaced by the old pass-through tables.push(...): anchor x1 to x0, blob ec53e2afb7e5 to e0b6c0c14fb9. Result 7 failed / 5 passed, in the predicted direction (red): every refusal pin plus the route pin went red; the unfiltered lists, the [] case and the qualified controls stayed green. Restore proven: blob back to ec53e2afb7e5 == HEAD, git diff HEAD empty, git status --porcelain empty. The subject is imported relatively (src), so no dist sat between mutation and run. LIVE MEASUREMENT: real SqlDriver dist against a private PG 16 cluster holding public.customers, sales.orders and sales.customers. At base eadea5720, ?schema=sales answered [customers] (default path) or both sales tables unfiltered. On this branch it answers THROW code=EXTERNAL_DATASOURCE_ERROR status=400; allowedSchemas ['public'] plus ?schema=sales answers [].",
"gates": "LOCAL, final head 118169806 (0f038913f merged with origin/main 5018fc303, no conflict): node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 68 commands, the same 68 as on 0f038913f. Each was run sequentially with its exit code captured before any pipe: exit 0 for 68 of 68. node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --ran ran2.list: 'Run reconciliation — 68 derived, 68 run, 0 NOT-MEASURED, 0 UNRUN', exit 0. Selected verdict lines: check-adr-0087-registration accepted .changeset/24664-remote-tables-schema-filter.md [BREAKING+bang+clause-②-narrowing] not-required (no-migration-prescription); check-changeset-no-major driven offline with the PR body as --event gave 'LEVEL AXIS: this PR declares clause-② no (narrowing), and no package ... it moves is graded patch' (exit 0); check:nul-bytes OK, 12428 files; check:dual-build-cjs-loads gave 111 require entry points across 69 packages loading. It exited 3 (PREREQUISITE NOT MET) on the earlier union over 0f038913f and was measured green on the final head. pnpm --filter @objectstack/spec check:generated after the merge: all 14 generated artifacts up to date, EXIT=0. Not run locally: test:repo (CI's Test Core), pnpm lint (CI-owned). CI on PR #24706, head 1181698060ab, read at report time. Completed with success: Check Changeset, Governed Surface Queue Guard, Check PR Size, Check Documentation Links, Flag docs affected by code changes, Dogfood Regression Gate, Lint · scoped · tooling self-tests, 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, Auto Label, filter. Skipped by selector: Build Docs, Console Pin Gate, Dogfood Verify CLI, the Dogfood shard matrix, Temporal Conformance, Packed-tarball smoke. in_progress (honest value, not awaited): Build Core, Test Core (1/6 to 6/6), Type Check · consumer gates / debt ledger / source gates / workspace, Lint · CI, release & engine gates, Lint · ESLint, Lint · PM dispatch-gates, Lint · docs & code guards, Lint · repo & tooling gates, Lint · scoped · query-options erasure, Lint · scoped · slot lookup & corpus.",
"line_budget": "393 = +389 / -4 (PR #24706: additions 389, deletions 4, changed_files 4)",
"files_changed": [
".changeset/24664-remote-tables-schema-filter.md",
"packages/services/service-datasource/src/__tests__/remote-tables-schema-attribution.test.ts",
"packages/services/service-datasource/src/admin-routes.ts",
"packages/services/service-datasource/src/external-datasource-service.ts"
],
"deviations": [
"ROUTE (A3), four axes, chose (b) for every in-tree dialect. Route (a) was measured out on two counts. First, IntrospectedTable has no declared schema field, and adding one is packages/spec (out of surface); qualifying the driver's names would re-key the introspection that managed-datasource consumers read by bare name. Second, Postgres introspection reaches only current_schemas(false), so sales off the search path is never read, and narrowing to it would answer an empty 200, still wrong. Business need: ?schema= producers are os datasource list-tables --schema and @objectstack/client datasources.external.listTables; the console schema browser sends none; no example sets allowedSchemas; nobody pulls real Postgres narrowing. Long-term: the service enforces exactly what the producer attests, with no dialect table (SQLite main, MySQL database, PG search path) as a second source of truth, and the qualified path stays live for a future schema-aware introspection. AI-error: declared filters are enforced or loudly refused, never a believable unfiltered list. Scope: no new spec key, flag, error code or driver capability. No driver file was declared or edited.",
"SQLite decided on the same axes: ?schema=main is refused like every other bare-name listing. The service does not learn SQLite's schema name; the only sender is the QA checklist step.",
"CHANGESET grade: minor, not the dispatch's default patch. Clause-② no (narrowing) is declared because a 400 replaces a 200, and check-changeset-no-major grades that arm minor during the launch window (verified offline with --event). ADR-0087 marker: not-required (no-migration-prescription).",
"Unsatisfiable filter answers [] (an empty allowedSchemas, or a ?schema= that allowedSchemas leaves out): no table can pass whatever its schema, so this answer needs no attribution. It is a refinement inside the card's 'narrow or refuse'.",
"admin-routes.ts gained one comment paragraph on the route and no code change. Both route spellings already map a throw from listRemoteTables to 400 EXTERNAL_DATASOURCE_ERROR, so no route code changed, packages/rest included.",
"The Postgres measurement used a private PG 16 cluster at /tmp/os-issue-24664-pg on port 47264, PID 16025. It could not live in the scratchpad: initdb runs as the postgres user, which cannot traverse the root-only (700) scratchpad parents. Stopped with pg_ctl -m fast after measuring, and the directory removed. Nobody else's server was touched.",
"Merged origin/main (5018fc303) before opening the PR, per AGENTS.md Multi-agent §10. The incoming commits touch none of service-datasource, driver-sql, the rest twin route, core or types. Closure rebuilt; spec check:generated green; package tests, typecheck, the rest twin tests and the 68-gate union were re-run on the merge head 118169806.",
"The first full package test run on 0f038913f was spelled 'pnpm --filter @objectstack/service-datasource test -- --maxWorkers=2', which is the bare-'--' trap: the whole package ran (the intent), and the worker cap may have been dropped. The re-run on 118169806 used no '--'.",
"test:repo was not run locally. It belongs to CI's Test Core, and the diff touches no repo-project test.",
"One os-verify-lock attempt returned 99 (queue-timeout, 540s; the holder was pid 11171, pnpm turbo run build). It was re-acquired with the same OS_VERIFY_LOCK_SLOT after doing lock-free work (re-deriving gates, starting the union)."
],
"mcp_calls": "0 — no MCP GitHub tool was called",
"api_writes": "2 relay strokes, each one POST /repos/objectstack-ai/objectstack/dispatches (204), executed as objectstack-fleet[bot] into 3 REST writes. Stroke 1, pr_create (run 39349934644): POST /repos/objectstack-ai/objectstack/pulls (draft #24706) and POST /repos/objectstack-ai/objectstack/issues/24706/assignees (os-warren). Stroke 2, this report: POST /repos/objectstack-ai/objectstack/issues/24664/comments. Plus git push of the branch, which is not REST. Reads were single-card REST GETs (issue, comments, triage comment, PR, check-runs).",
"open_questions": [],
"out_of_scope_findings": [
"class: a · reach: named real producer — a Postgres database default search_path naming two schemas (ALTER DATABASE ... SET search_path = public, sales). Measured on live PG 16 through SqlDriver.introspectSchema and through listRemoteTables, where orders came back with columnCount 0. The public HTTP door was not exercised. · evidence: introspectSchema lists the tables of every current_schemas(false) schema keyed by bare name, so sales.customers is silently dropped behind public.customers. introspectColumns reads knex(name).columnInfo(), which resolves only the current schema, so sales.orders reports zero columns (measured: 'orders: columns=[]'); a draft or catalog from it would carry no fields. Landing: packages/drivers/driver-sql/src/sql-driver.ts introspectSchema / introspectColumns. · dedupe words: postgres introspectSchema search_path two schemas zero columns; introspectColumns columnInfo current_schema; same-named table second schema dropped introspection",
"carrier: none · noted, not filed — QA checklist item integration-system.external-schema-introspection now reads differently: step 2 (?schema=main on the stock SQLite showcase_external) answers 400 EXTERNAL_DATASOURCE_ERROR, and knownGaps[0] describes the old no-op. It is named in PR #24706's Acceptance notes so the next checklist pass restates it.",
"carrier: none · noted, not filed — the allowedSchemas row in packages/spec/liveness/datasource.json still says the filter 'only bites on tables whose schema can be attributed'. Its anchors (listRemoteTables and the const allowed = ds?.external?.allowedSchemas read) still resolve; only the prose is stale.",
"carrier: none · noted, not filed — allowedSchemas is consulted only by listRemoteTables, not by generateObjectDraft, importObject or refreshCatalog. ADR-0015 §6.1 scopes the filter to listRemoteTables.",
"carrier: none · noted, not filed — real Postgres narrowing needs a schema-scoped introspection, meaning a schema on IntrospectedTable or a schema-taking introspectSchema. That is a packages/spec contract decision with no measured consumer."
]
}
ACCEPT → PR #24706 comment 6280888463 · domain:services seat 2 · 2026-10-20T01:05Z · head 1181698060, after contract review 6280869258 (PASS). Landing waits for every check on the head.
Activity
objectstack-fleet commentedon Oct 19, 2026
Claim: PM loop round 5 · 2026-10-19T23:08Z
Session:
session_01LR1cD9JqgkeqY7k9rrZH8sAccount:
os-warren(the seat's linked user asGET /useranswers it; always the card's assignee)Branch:
claude/issue-24664-remote-tables-schema-filterWorktree:
objectstack-issue-24664Domain:
domain:servicesSeat:
domain:services#2(seat post #21118)File surface:
packages/services/service-datasource/src/**(external-datasource-service.ts's remote-table listing, its?schema=filter andallowedSchemasguard, andadmin-routes.ts's route if the answer changes there), new or extended test files beside them; a changeset; a driver's introspection file only if declared in the report first; ⛔ notpackages/spec/**(stop on breach; explain in the report)Container & model:
S,mode:subagent,model: opus(the default tier;dispatch-gates --tierprinted no path-derived mandate for this surface)Clause-②: no
Responsibility: the remote-table listing's schema filter and allow-list (this lane,
service-datasource) |?schema=narrows to the named schema or refuses explicitly, never a silently wrong 200;allowedSchemasis judged the same way (card) | admins browsing an external Postgres or SQLite datasource's tables (#24619 row c)Thread-read: none
Serial constraints cleared: no open PR touches
packages/services/service-datasource/(a file scan of every open PR at this claim). #24619's row (a) isdomain:engineseat 1's (6277262398), on another surface.Generated by Claude Code
objectstack-fleet commentedon Oct 20, 2026
os-dev-report
{ "issue": 24664, "status": "done", "branch": "claude/issue-24664-remote-tables-schema-filter", "pr": "https://github.com/objectstack-ai/objectstack/pull/24706", "session": "session_01LR1cD9JqgkeqY7k9rrZH8s — the harness-stamped Claude-Session id of this run (subagent, so the parent seat's id)", "premise_still_valid": true, "summary": "listRemoteTables now applies a schema filter in force (?schema= or the datasource's external.allowedSchemas) to every table or refuses: where the introspection names no schema for a table (the in-tree SqlDriver, every dialect, measured on live PostgreSQL 16 and SQLite) it throws 400 EXTERNAL_DATASOURCE_ERROR, which both route spellings already serve unchanged, instead of answering a 200 with tables the filter never narrowed. A producer that reports qualified names is narrowed as before (the old qualified fakes kept as the control), a filter no table can pass answers [], and an unfiltered listing is unchanged. Route (b) for every dialect: no driver file and nothing under packages/spec touched. Declared Clause-② no (narrowing) with a minor changeset, the grade the level gate asks for that arm.", "tests": "head 118169806. NEW packages/services/service-datasource/src/__tests__/remote-tables-schema-attribution.test.ts, 12 cases: a real in-memory SqlDriver SQLite introspection (unfiltered list kept; ?schema= and allowedSchemas refused), a Postgres fake holding the measured real introspection on the default path and on searchPath sales (?schema=sales refused, which is the card's row; refused even when every table is in sales; allowedSchemas refused; unsatisfiable filter answers []; unfiltered list kept), the qualified-name control (narrows by ?schema=, by allowedSchemas, by both; one bare name among qualified refuses), and the route via real HonoHttpServer (GET /api/v1/datasources/pg/remote-tables?schema=sales answers 400, success false, error.code EXTERNAL_DATASOURCE_ERROR; without ?schema= 200 with the table). pnpm --filter @objectstack/service-datasource test: Test Files 46 passed (46), Tests 850 passed (850). pnpm --filter @objectstack/service-datasource typecheck: exit 0, and tsc --listFiles counts the new test file 1 time. pnpm --filter @objectstack/rest exec vitest run src/remote-tables-twin.equivalence.test.ts src/external-datasource-envelope.conformance.test.ts: 2 files, 26 passed (the rest vitest config aliases service-datasource to src). All three ran under os-verify-lock, VERDICT command-exit 0. ABLATION (one): node scripts/ablation-replace.mjs wrap mode, under the lock, on 0e100d3a4, anchor 'unattributed.push(table.name);' replaced by the old pass-through tables.push(...): anchor x1 to x0, blob ec53e2afb7e5 to e0b6c0c14fb9. Result 7 failed / 5 passed, in the predicted direction (red): every refusal pin plus the route pin went red; the unfiltered lists, the [] case and the qualified controls stayed green. Restore proven: blob back to ec53e2afb7e5 == HEAD, git diff HEAD empty, git status --porcelain empty. The subject is imported relatively (src), so no dist sat between mutation and run. LIVE MEASUREMENT: real SqlDriver dist against a private PG 16 cluster holding public.customers, sales.orders and sales.customers. At base eadea5720, ?schema=sales answered [customers] (default path) or both sales tables unfiltered. On this branch it answers THROW code=EXTERNAL_DATASOURCE_ERROR status=400; allowedSchemas ['public'] plus ?schema=sales answers [].", "gates": "LOCAL, final head 118169806 (0f038913f merged with origin/main 5018fc303, no conflict): node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 68 commands, the same 68 as on 0f038913f. Each was run sequentially with its exit code captured before any pipe: exit 0 for 68 of 68. node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --ran ran2.list: 'Run reconciliation — 68 derived, 68 run, 0 NOT-MEASURED, 0 UNRUN', exit 0. Selected verdict lines: check-adr-0087-registration accepted .changeset/24664-remote-tables-schema-filter.md [BREAKING+bang+clause-②-narrowing] not-required (no-migration-prescription); check-changeset-no-major driven offline with the PR body as --event gave 'LEVEL AXIS: this PR declares clause-② no (narrowing), and no package ... it moves is graded patch' (exit 0); check:nul-bytes OK, 12428 files; check:dual-build-cjs-loads gave 111 require entry points across 69 packages loading. It exited 3 (PREREQUISITE NOT MET) on the earlier union over 0f038913f and was measured green on the final head. pnpm --filter @objectstack/spec check:generated after the merge: all 14 generated artifacts up to date, EXIT=0. Not run locally: test:repo (CI's Test Core), pnpm lint (CI-owned). CI on PR #24706, head 1181698060ab, read at report time. Completed with success: Check Changeset, Governed Surface Queue Guard, Check PR Size, Check Documentation Links, Flag docs affected by code changes, Dogfood Regression Gate, Lint · scoped · tooling self-tests, 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, Auto Label, filter. Skipped by selector: Build Docs, Console Pin Gate, Dogfood Verify CLI, the Dogfood shard matrix, Temporal Conformance, Packed-tarball smoke. in_progress (honest value, not awaited): Build Core, Test Core (1/6 to 6/6), Type Check · consumer gates / debt ledger / source gates / workspace, Lint · CI, release & engine gates, Lint · ESLint, Lint · PM dispatch-gates, Lint · docs & code guards, Lint · repo & tooling gates, Lint · scoped · query-options erasure, Lint · scoped · slot lookup & corpus.", "line_budget": "393 = +389 / -4 (PR #24706: additions 389, deletions 4, changed_files 4)", "files_changed": [ ".changeset/24664-remote-tables-schema-filter.md", "packages/services/service-datasource/src/__tests__/remote-tables-schema-attribution.test.ts", "packages/services/service-datasource/src/admin-routes.ts", "packages/services/service-datasource/src/external-datasource-service.ts" ], "deviations": [ "ROUTE (A3), four axes, chose (b) for every in-tree dialect. Route (a) was measured out on two counts. First, IntrospectedTable has no declared schema field, and adding one is packages/spec (out of surface); qualifying the driver's names would re-key the introspection that managed-datasource consumers read by bare name. Second, Postgres introspection reaches only current_schemas(false), so sales off the search path is never read, and narrowing to it would answer an empty 200, still wrong. Business need: ?schema= producers are os datasource list-tables --schema and @objectstack/client datasources.external.listTables; the console schema browser sends none; no example sets allowedSchemas; nobody pulls real Postgres narrowing. Long-term: the service enforces exactly what the producer attests, with no dialect table (SQLite main, MySQL database, PG search path) as a second source of truth, and the qualified path stays live for a future schema-aware introspection. AI-error: declared filters are enforced or loudly refused, never a believable unfiltered list. Scope: no new spec key, flag, error code or driver capability. No driver file was declared or edited.", "SQLite decided on the same axes: ?schema=main is refused like every other bare-name listing. The service does not learn SQLite's schema name; the only sender is the QA checklist step.", "CHANGESET grade: minor, not the dispatch's default patch. Clause-② no (narrowing) is declared because a 400 replaces a 200, and check-changeset-no-major grades that arm minor during the launch window (verified offline with --event). ADR-0087 marker: not-required (no-migration-prescription).", "Unsatisfiable filter answers [] (an empty allowedSchemas, or a ?schema= that allowedSchemas leaves out): no table can pass whatever its schema, so this answer needs no attribution. It is a refinement inside the card's 'narrow or refuse'.", "admin-routes.ts gained one comment paragraph on the route and no code change. Both route spellings already map a throw from listRemoteTables to 400 EXTERNAL_DATASOURCE_ERROR, so no route code changed, packages/rest included.", "The Postgres measurement used a private PG 16 cluster at /tmp/os-issue-24664-pg on port 47264, PID 16025. It could not live in the scratchpad: initdb runs as the postgres user, which cannot traverse the root-only (700) scratchpad parents. Stopped with pg_ctl -m fast after measuring, and the directory removed. Nobody else's server was touched.", "Merged origin/main (5018fc303) before opening the PR, per AGENTS.md Multi-agent §10. The incoming commits touch none of service-datasource, driver-sql, the rest twin route, core or types. Closure rebuilt; spec check:generated green; package tests, typecheck, the rest twin tests and the 68-gate union were re-run on the merge head 118169806.", "The first full package test run on 0f038913f was spelled 'pnpm --filter @objectstack/service-datasource test -- --maxWorkers=2', which is the bare-'--' trap: the whole package ran (the intent), and the worker cap may have been dropped. The re-run on 118169806 used no '--'.", "test:repo was not run locally. It belongs to CI's Test Core, and the diff touches no repo-project test.", "One os-verify-lock attempt returned 99 (queue-timeout, 540s; the holder was pid 11171, pnpm turbo run build). It was re-acquired with the same OS_VERIFY_LOCK_SLOT after doing lock-free work (re-deriving gates, starting the union)." ], "mcp_calls": "0 — no MCP GitHub tool was called", "api_writes": "2 relay strokes, each one POST /repos/objectstack-ai/objectstack/dispatches (204), executed as objectstack-fleet[bot] into 3 REST writes. Stroke 1, pr_create (run 39349934644): POST /repos/objectstack-ai/objectstack/pulls (draft #24706) and POST /repos/objectstack-ai/objectstack/issues/24706/assignees (os-warren). Stroke 2, this report: POST /repos/objectstack-ai/objectstack/issues/24664/comments. Plus git push of the branch, which is not REST. Reads were single-card REST GETs (issue, comments, triage comment, PR, check-runs).", "open_questions": [], "out_of_scope_findings": [ "class: a · reach: named real producer — a Postgres database default search_path naming two schemas (ALTER DATABASE ... SET search_path = public, sales). Measured on live PG 16 through SqlDriver.introspectSchema and through listRemoteTables, where orders came back with columnCount 0. The public HTTP door was not exercised. · evidence: introspectSchema lists the tables of every current_schemas(false) schema keyed by bare name, so sales.customers is silently dropped behind public.customers. introspectColumns reads knex(name).columnInfo(), which resolves only the current schema, so sales.orders reports zero columns (measured: 'orders: columns=[]'); a draft or catalog from it would carry no fields. Landing: packages/drivers/driver-sql/src/sql-driver.ts introspectSchema / introspectColumns. · dedupe words: postgres introspectSchema search_path two schemas zero columns; introspectColumns columnInfo current_schema; same-named table second schema dropped introspection", "carrier: none · noted, not filed — QA checklist item integration-system.external-schema-introspection now reads differently: step 2 (?schema=main on the stock SQLite showcase_external) answers 400 EXTERNAL_DATASOURCE_ERROR, and knownGaps[0] describes the old no-op. It is named in PR #24706's Acceptance notes so the next checklist pass restates it.", "carrier: none · noted, not filed — the allowedSchemas row in packages/spec/liveness/datasource.json still says the filter 'only bites on tables whose schema can be attributed'. Its anchors (listRemoteTables and the const allowed = ds?.external?.allowedSchemas read) still resolve; only the prose is stale.", "carrier: none · noted, not filed — allowedSchemas is consulted only by listRemoteTables, not by generateObjectDraft, importObject or refreshCatalog. ADR-0015 §6.1 scopes the filter to listRemoteTables.", "carrier: none · noted, not filed — real Postgres narrowing needs a schema-scoped introspection, meaning a schema on IntrospectedTable or a schema-taking introspectSchema. That is a packages/spec contract decision with no measured consumer." ] }objectstack-fleet commentedon Oct 20, 2026
ACCEPT → PR #24706 comment 6280888463 ·
domain:servicesseat 2 · 2026-10-20T01:05Z · head1181698060, after contract review6280869258(PASS). Landing waits for every check on the head.Generated by Claude Code
objectstack-fleet commentedon Oct 20, 2026
Landed ·
domain:servicesseat 2 ·os-warren·session_01LR1cD9JqgkeqY7k9rrZH8s· 2026-10-20T02:14Zauto_merge_enabled2026-10-20T01:18Z →added_to_merge_queue2026-10-20T01:20Z →merged2026-10-20T02:14Zorigin/main60571dd179is an ancestor (git merge-base --is-ancestor, exit 0)completedby the PR'sFixes #24664; this act clearspm:dispatchedand the assigneeContract review
6280869258(PASS) and ACCEPT6280888463are on the PR.driver-sql's multi-schema introspection is #24707.Generated by Claude Code