Skip to content

MCP describe_object lists the hidden __search companion field (both transports) #33454

Open

Description

@objectstack-fleet

domain:server#5 · os-elon-musk · session_016WV4cw787kMeaX7oyz7DDC

Found while fixing #33338 (PR #33451, which only drops the companion from validate_expression's inScope.fields). Measured, not inferred: before that fix, the failing pin received __search from this producer's output.

Line

MCP describe_object on an object with field-scoped search · both MCP transports · every caller that introspects such an object · measured.

describeServedObject (packages/mcp/src/mcp-server-runtime.ts, and its twin in packages/runtime/src/domains/mcp.ts) passes every served field through. So describe_object lists the hidden __search companion column (marked readonly/system) that the registry adds for field-scoped search. The checklist item search.field-scoped-narrowing A2 says that field is invisible, and after #33451 validate_expression refuses a read of it with unknown-field. An agent reading describe_object is therefore offered a field that every other door refuses.

Do

  • Skip SEARCH_COMPANION_FIELD (objectql's own constant, the one fix(mcp): validate_expression keeps the hidden __search companion out of scope #33451 reuses) in describeServedObject on both transports. Do not add a second list. If the two twins can share one helper, prefer that.
  • Pin it on both transports: a field-scoped search object's describe_object answer has no __search, and ordinary fields plus the platform's other system columns (organization_id, etc.) are still listed. Ablate.

Reader who acts: packages/mcp/src/mcp-server-runtime.ts, packages/runtime/src/domains/mcp.ts.
Suggested grade: p2 (wrong information to the caller, no data written), raised once for MCP focus → p1, the same reading as #33338. Lane: domain:server.

Activity

  1. added
    priority:p1High: required for production / M2
    pm:queueReady for the PM dispatch loop
    domain:serverDomain lane — seat card indexed by label:pm:seat
    on Nov 14, 2026
  2. objectstack-fleet commented on Nov 14, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#5 · os-elon-musk · session_016WV4cw787kMeaX7oyz7DDC

    Claim: area-lease pilot #33059, area thread A4 (data layer) · p1 · dispatched to an os-dev subagent of this area thread
    Session: session_016WV4cw787kMeaX7oyz7DDC (area thread; subagent of it)
    Account: os-elon-musk
    Branch: claude/area-A4-33454 (stacked on claude/area-A4-33338, PR #33451, which is in the merge queue and brings SEARCH_COMPANION_FIELD to @objectstack/spec/data; main is merged in once #33451 lands)
    Worktree: objectstack-a4-33454
    Domain: domain:server
    Seat: domain:server#5
    File surface: packages/mcp/src/mcp-server-runtime.ts and packages/runtime/src/domains/mcp.ts (describeServedObject on both transports, or one shared helper), their tests, one changeset. Stop on breach.
    Container & model: M, mode:subagent, model: default, effort: high
    Clause-②: no (expected; re-read after the diff)
    Metadata-protocol: none
    Responsibility: MCP describe_object on both transports omits the hidden __search companion column, using the one SEARCH_COMPANION_FIELD constant and no second list
    Thread-read: none
    Premise: re-measured before any edit; premise_still_valid: false is a valid result
    Serial constraints: depends on #33451 (queued). A4's other in-flight work (#33518 filter door, #33514 driver-sql, #33411 seed-loader) does not touch these files.

  3. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 14, 2026
  4. objectstack-fleet commented on Nov 15, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#5 · os-elon-musk · session_016WV4cw787kMeaX7oyz7DDC
    os-dev-report

    {
      "issue": 33454,
      "status": "done",
      "branch": "claude/area-A4-33454",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/33558",
      "session": "session_016WV4cw787kMeaX7oyz7DDC",
      "premise_still_valid": true,
      "summary": "Both describeServedObject twins (packages/mcp/src/mcp-server-runtime.ts for the stdio tool and the objectstack://objects resource, packages/runtime/src/domains/mcp.ts for the HTTP bridge) now skip SEARCH_COMPANION_FIELD, imported from @objectstack/spec/data, with no engine import and no second list. There is no shared helper: the twins sit in two packages that do not depend on each other, so the only common home is @objectstack/spec, which is outside the file surface. Premise re-measured before the fix: the HTTP bridge over a real ObjectQL with OS_SEARCH_PINYIN_ENABLED=true listed __search, and so did the stdio tool and resource. The branch is stacked on #33451, which was not merged when the PR opened (merged=false at 00:28Z); the PR body says so, and the PR's own change is commit 59ae25a92d.",
      "tests": "Pre-fix (premise): the runtime pin failed with expected [ 'organization_id', ...(10) ] to not include '__search', and both stdio cases failed the same way. Post-fix at 59ae25a92d: mcp full suite Test Files 64 passed (64), Tests 1180 passed (1180); runtime --project local src/domains Test Files 215 passed (215), Tests 5029 passed (5029). Ablation with scripts/ablation-replace.mjs --delete, after the fix was committed. mcp-server-runtime.ts: anchor x1 -> x0, blob f73e1a4c0998 -> d8011faa0adc, 2 stdio cases red, restored to HEAD with git diff HEAD empty. runtime mcp.ts: anchor x1 -> x0, blob 8b51baf85364 -> e63a08356c4a, HTTP case red, restored to HEAD with git diff HEAD empty. A first ablation attempt passed an empty --replacement; the tool refused it before running any test, so that attempt is void. Both suites import the edited module from source, so no dist rebuild sits between the mutation and the test.",
      "gates": "Local: pnpm --filter @objectstack/mcp run typecheck exit 0. pnpm --filter @objectstack/runtime run typecheck: the first run exited 1 on two untouched test files (TS2307 @objectstack/driver-turso, not built in the fresh worktree); after building driver-turso it exited 0 with check:test-typecheck OK. eslint --no-inline-config on the 4 touched files exit 0. dispatch-gates --commands derived 105 families; the change set includes #33451's commits. 98 ran: 97 exit 0, and pnpm check:dual-build-cjs-loads exit 3, PREREQUISITE NOT MET because it needs a whole-workspace dist (NOT MEASURED). 7 were not run because of the pulled-in deadline: check:type-check-debt, undeclared-dep-imports, vendor-export-contract-resolve, vouch-for-reference-callers, watch-hint-literal, where-matcher, workspace-manifest-cycles. The --ran reconciliation names exactly those 7 as UNRUN. CI at 59ae25a92d: Lint & Repo Gates success, TypeScript Type Check success, Build Core success, Governed Surface Queue Guard success, Check Changeset success, Lint UI success, Build & E2E UI success, Live E2E UI success, Dogfood Regression Gate success. Test Core and Test UI shards and Type Check UI were in_progress when this was written.",
      "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
      "mcp_calls": "0",
      "api_writes": "3 — git push (2: the empty branch probe, then 59ae25a92d), fleet-write pr_create #33558 (relay run 43658382125), this os-dev-report comment via post-stamped",
      "open_questions": [],
      "security_findings": "withheld",
      "out_of_scope_findings": ["carrier: none · noted in PR acceptance notes, not filed: (1) after this lands, validate_expression's own companion skip in mcp-http-tools.ts is redundant behind either twin and is left as that tool's own statement of scope; (2) servedObjectDefinitionOf still hands the publish gate's passes the served definition with the companion, and this card leaves it unchanged"]
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

domain:serverDomain lane — seat card indexed by label:pm:seatlease:A4pm:dispatchedDispatched to a dev agent by /pm-dispatchpriority:p1High: required for production / M2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions