Skip to content

spec: a per-object, read-only AI exposure declaration so an agent can read a declared system object through the MCP record tools (#32442 read half) #32865

Closed

Description

@objectstack-fleet

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

Filing gate: executing a recorded ruling. The maintainer ruled A on the read half of #32442 (this seat's decision card, verbatim 「同意」; recorded on #32442). A metadata-protocol addition is a spec sub-card (.claude/skills/pm-dispatch/references/lanes/spec.md), so this card carries the spec half and #32442's read half is Blocked-by: it. ⛔ Not a claim; triage sets the lane and grade.

维护者速读

经理问 AI「我有哪些待审批?」今天答不了:MCP 的读工具一律拒绝系统表,审批请求表也是系统表。你已裁 A:在对象上加一个按对象声明的只读 AI 开放键,由审批请求表自己声明,AI 用现有的查询工具看到与控制台「我的待审批」相同的行。本卡只做 spec 那一半(键的形状与规则),产品那一半在 #32442。

Measured (origin/main, read by the #32442 dev and an independent review)

Do (the shape the ruling and the review set)

Not here (the server half, #32442)

The bridge attesting the object, the three mcp guards honouring the attestation, sys_approval_request declaring the key, and acceptance through a real MCP client (an approver sees only their rows, a non-participant sees none, payloads redacted as today).

Related: #32442 (product card), #27681, ADR-0011, ADR-0066.

Activity

  1. objectstack-fleet commented on Nov 12, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · hotlong · session_01Q4EjjMnyLqJdzuktEmRPXH

    Path: none

    Triage: first touch (requested by domain:server#5) → domain:spec · p1 · pm:queue · 2026-11-12T22:16Z

    ⛔ Not a claim.


    Generated by Claude Code

  2. added
    area:aiAI-native — agent / tool / skill metadata, and the MCP surface an agent drives
    domain:specDomain lane — seat card indexed by label:pm:seat
    pm:queueReady for the PM dispatch loop
    priority:p1High: required for production / M2
    on Nov 12, 2026
  3. objectstack-fleet commented on Nov 13, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#3 · os-elon-musk · session_016WV4d1T5HEokjRgR6vCBX8

    Claim: PM loop round 1 (executes the maintainer's ruling A on #32442's read half; triage 6837437290, p1)
    Session: session_016WV4d1T5HEokjRgR6vCBX8 (seat); dev = a card thread of this seat, its session posted on this card when it amends the Branch line
    Account: os-elon-musk
    Branch: claude/issue-32865-object-ai-read-exposure (the card thread amends this line to its own designated branch on first push)
    Worktree: objectstack-issue-32865
    Domain: domain:spec
    Seat: domain:spec#3
    File surface: packages/spec/src/data/object.zod.ts (one per-object read-only AI exposure key, the region of ObjectCapabilities ~:268 or a sibling block the dev measures and names), its tests, a packages/lint rule refusing the key on a non-sys_* object and on the stored-metadata-body family (the dev names the file), regenerated spec artefacts the build demands (authorable surface, JSON schema, references), one changeset. NOT packages/mcp and NOT sys_approval_request (the server half, #32442). Stop on breach.
    Container & model: M, mode:thread, model: TIER_DEFAULT, effort: high; the seat runs one CONTRACT_REVIEW_TIER review before the queue (reason: contract-review.md face rule — a metadata-protocol addition)
    Clause-②: yes (widening)
    Metadata-protocol: added
    Responsibility: objectstack: the object schema in packages/spec declares no per-object AI read exposure, so the MCP read tools refuse every sys_* object by name and an approver cannot ask the AI for their pending approvals | the only switch is host-wide allowSystemObjects, which no deployment opens | every MCP client of a hosted tenant; measured by the #32442 dev and an independent review (card Measured)
    Thread-read: 6837437290
    Premise: holds as filed (origin/main a6be0fe: ObjectCapabilities at object.zod.ts:268 declares apiEnabled / apiMethods and no AI exposure key) — the dev re-measures before building
    Serial constraints cleared: none — #32890 (this seat) edits object.zod.ts to move the stage-field refinement and the icon leaf into two modules, a different region from ObjectCapabilities; whichever lands second merges main. #32911 edits packages/mcp only (outside this surface).

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

    @objectstack-fleet
    ContributorAuthor

    domain:spec#3 · os-elon-musk · session_016WV4czFmroo4m96P6zVdd1

    Claim: PM loop round 1 (executes the maintainer's ruling A on #32442's read half; triage 6837437290, p1) — re-posted whole by the card thread on its first push; replaces the branch named by claim 6839742814
    Session: session_016WV4czFmroo4m96P6zVdd1 (dev: the card thread of seat session session_016WV4d1T5HEokjRgR6vCBX8)
    Account: os-elon-musk
    Branch: claude/project-thread-lgpfso
    Worktree: objectstack-issue-32865
    Domain: domain:spec
    Seat: domain:spec#3
    File surface: packages/spec/src/data/object.zod.ts (one per-object read-only AI exposure key in ObjectCapabilities, enable.aiReadable, its aliases and write-arm guidance, and the refusal call in ObjectSchema's refinement), packages/spec/src/data/ai-read-exposure.ts (new: the refusal and the one reading isAiReadExposed; the dev names it in place of a packages/lint rule, because the parse refusal reaches every door that parses an object, os validate included), packages/spec/src/data/index.ts (one re-export), packages/spec/liveness/object.json (one planned row), their tests, regenerated spec artefacts the build demands (authorable surface, JSON schema, references, api surface), one changeset. NOT packages/mcp and NOT sys_approval_request (the server half, #32442). Stop on breach.
    Container & model: M, mode:thread, model: TIER_DEFAULT, effort: high; the seat runs one CONTRACT_REVIEW_TIER review before the queue (reason: contract-review.md face rule — a metadata-protocol addition)
    Clause-②: yes (widening)
    Metadata-protocol: added
    Responsibility: objectstack: the object schema in packages/spec declares no per-object AI read exposure, so the MCP read tools refuse every sys_* object by name and an approver cannot ask the AI for their pending approvals | the only switch is host-wide allowSystemObjects, which no deployment opens | every MCP client of a hosted tenant; measured by the #32442 dev and an independent review (card Measured)
    Thread-read: 6839742814
    Premise: holds (origin/main a888c5c: ObjectCapabilities declares apiEnabled / apiMethods and no AI exposure key; re-measured by the dev)
    Serial constraints cleared: none — #32890 (this seat) edits object.zod.ts to move the stage-field refinement and the icon leaf into two modules, a different region from ObjectCapabilities; whichever lands second merges main. #32911 edits packages/mcp only (outside this surface).

  6. objectstack-fleet commented on Nov 13, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#3 · os-elon-musk · session_016WV4czFmroo4m96P6zVdd1
    os-dev-report

    os-dev report — #32865 · PR #32971 · head 9782f9e

    {
      "issue": 32865,
      "status": "done",
      "branch": "claude/project-thread-lgpfso",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/32971",
      "session": "session_016WV4czFmroo4m96P6zVdd1",
      "premise_still_valid": true,
      "summary": "Ruling A (6837430865), spec half. ObjectCapabilities gains enable.aiReadable (optional boolean): the read-only AI exposure of a sys_* object, the read counterpart of actions' ai.exposed; no write arm, no deployment switch, allowSystemObjects untouched, packages/mcp untouched. Placement measured: enable, because the MCP record tools already read the object's enable block (stdio-data-bridge apiEnabled/apiMethods gate; both bridges carry enableFeatures: def.enable). Mechanism: refused at PARSE in ObjectSchema's existing superRefine (not a packages/lint rule; a parse refusal is a superset: os validate reports it and defineStack, module load and the save door also reach it) on any non-sys_* object (true and false) and on the stored-metadata family, whose source of truth is STORED_METADATA_BODY_OBJECTS (sys_metadata, sys_metadata_history) in packages/spec/src/kernel/stored-metadata-body-objects.ts, imported not copied. isAiReadExposed (exported from @objectstack/spec/data) is the one reading for the server half: family judged before the key is read, boolean true only. Liveness row planned; Studio form omits the key (reconciliation ledger row). Merged key for #32442's seat: enable.aiReadable, reading isAiReadExposed.",
      "tests": "packages/spec/src/data/ai-read-exposure.test.ts 17/17. Ablations via scripts/ablation-replace.mjs (anchor x1->x0 proven on disk, EXIT-trap restore, blob == HEAD after each; spec tests import src, no dist leg): A1 off-sys_* refusal removed -> 3 red; A2 family refusal removed -> 3 red; A3 family-before-key in isAiReadExposed removed -> 2 red; A4 sys_* acceptance removed -> 1 red; A5 write-arm key added to enable -> 1 red. On 9782f9e7fc: pnpm --filter @objectstack/spec test Test Files 837 passed (837), Tests 26754 passed, 1 todo, VERDICT command-exit 0; spec typecheck exit 0; @objectstack/lint vitest Test Files 200 passed (200), Tests 8579 passed. Two existing tests updated for the new key: alias-integrity (enable guidance list) and metadata-form-zod-reconciliation (omit ledger row).",
      "gates": "dispatch-gates --commands on 9782f9e7fc: 113 derived, all 113 exit 0 after a whole-tree turbo build (VERDICT command-exit 0); check:type-check-debt run under os-verify-lock. dispatch-gates --ran: 113 derived, 113 run, 0 NOT-MEASURED, 0 UNRUN. check:generated: all 14 artifacts up to date. CI check-runs: in_progress at report time.",
      "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
      "mcp_calls": "0",
      "api_writes": "3 — post-stamped claim re-post 6839889768 (POST issues/32865/comments via relay); fleet-write pr_create #32971 (POST pulls); this report (POST issues/32865/comments via relay)",
      "open_questions": [
        { "question": "The card says the off-sys_* declaration is refused by lint; this PR refuses it at parse. Keep parse?", "options": ["A keep the parse refusal (covers os validate plus defineStack, module load and the save door)", "B move it to a packages/lint rule"], "recommendation": "A, because it is a strict superset of the lint door and follows the same refinement's precedents; the contract review confirms" }
      ],
      "security_findings": "none",
      "out_of_scope_findings": [
        "carrier: #32442 · whether a tenant object overlay of a sys_* object can carry enable.aiReadable is the server half's to measure; the attestation should read isAiReadExposed on the registered definition. Object extensions cannot carry enable (ObjectExtensionSchema is closed) · noted, not filed",
        "carrier: none · three copies of the sys_ name predicate (packages/mcp mcp-http-tools.ts, packages/runtime action-execution.ts isSystemObjectName, module-private in ai-read-exposure.ts); spec cannot import the runtime ones · noted in Acceptance notes, not filed"
      ]
    }
  7. objectstack-fleet commented on Nov 13, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#3 · os-elon-musk · session_016WV4d1T5HEokjRgR6vCBX8

    Landed · 2026-11-13T02:34Z

    Reading Value
    PR #32971 MERGED 2026-11-13T02:33:22Z as 04c35f0952 through the merge queue (seat ACCEPT 6841378331; contract review PASS 6841030247, open question answered A: parse refusal)
    This card closed completed by Fixes #32865
    Key on main enable.aiReadable on ObjectCapabilities; reader isAiReadExposed from @objectstack/spec/data; refused at parse off sys_* and on the STORED_METADATA_BODY_OBJECTS family
    Unblocked #32442 (server half, domain:server#5 told on its mailbox #32830); #32974 (skills follow-up, Blocked-by: #32971 now merged)

    State change: pm:dispatched removed in this stroke; the card is done.

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

Metadata

Metadata

Assignees

Labels

area:aiAI-native — agent / tool / skill metadata, and the MCP surface an agent drivesdomain:specDomain lane — seat card indexed by label:pm:seatpriority: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