Skip to content

Implement ADR-0063/0064: split ask/build agents by surface; tool scoping #2168

Closed

Description

@xuyushun441-sys

Implementation tracking for ADR-0063 (two agents bound by surface) and ADR-0064 (tool scoping). Decision PR: #2167. Landscape: docs/audits/2026-06-ask-build-agent-development-assessment.md.

Split the personas (reverse ADR-0040 unified assistant)

  • Remove the unified ask-carries-all-skills definition + per-turn intent preamble (service-ai/src/agents/data-chat-agent.ts); ask carries only surface:'ask' skills.
  • Delete the buildRegisterActive degradation shim (service-ai/src/agent-runtime.ts:179) — no longer needed once surfaces are separate.
  • Bind agent → surface in ../objectui (data console → ask, Studio → build); keep the picker hidden/builder-only.

Naming (finish both sides of the rename)

  • service-ai/src/agents/data-chat-agent.ts → ask-agent.ts; DEFAULT_DATA_AGENT_NAME → ASK_AGENT_NAME (keep LEGACY_DATA_AGENT_NAME='data_chat').
  • ../cloud/service-ai-studio: make build the canonical id (currently still metadata_assistant); register metadata_assistant as the permanent alias.
  • Prose sweep: "Data/Metadata Assistant" → ask/build; aliases live only in the alias table.

Skill ↔ agent affinity (ADR-0063 §3)

  • Add surface: 'ask' | 'build' | 'both' to SkillSchema (spec/src/ai/skill.zod.ts); backfill the four built-in skills.

Tool scoping (ADR-0064)

  • Remove the global fall-through in tool resolution; resolve wildcards against skill-claimed names only (kill the actions_executor empty-array + fall-through hack).
  • Add a surface:'both' schema_reader skill owning describe_object/list_objects/query_data; stop dual-listing by comment.
  • Make incompatible skill↔agent binding a fast load error in resolveActiveSkills.
  • Tests: tools(ask) contains no create_*/*_metadata/blueprint tools (cloud + OSS); authoring tools present only under build.

Withdraw tenant custom agents (ADR-0063 §2)

  • spec/src/kernel/metadata-plugin.zod.ts: set agent type allowRuntimeCreate:false, allowOrgOverride:false.
  • Filter custom agents from the runtime catalog; drop the app.defaultAgent custom-agent guidance in the cloud plugin.

Deferred

  • D4 deployment guardrail-floor schema — defer (no tenant agent to floor once the above lands).

Activity

  1. xuyushun441-sys commented on Jun 22, 2026

    @xuyushun441-sys
    CollaboratorAuthor

    Implemented and merged across framework + cloud:

    • framework feat(ai): split ask/build agents by surface + tool scoping (ADR-0063/0064) #2181 (merged, main e411a8219) — surface on SkillSchema/AgentSchema; ask persona split (dropped the unified INTENT-FIRST classifier + buildRegisterActive shim); schema_reader (surface:'both') for the shared reads; affinity enforced as a load error in resolveActiveSkills; agent type allowRuntimeCreate:false, allowOrgOverride:false + catalog filtered to platform agents; data-chat-agent.ts→ask-agent.ts.
    • cloud objectstack-ai/cloud#417 (merged, main 3d72d8790) — build agent surface:'build' + attaches schema_reader; metadata_authoring/solution_design → surface:'build'; stopped dual-listing the shared reads; dropped the custom-agent guidance.
    • objectui — no change needed: surface binding (alias groups, isBuildAgent/isAskAgent, aiStudio gate, hidden picker) already in place.

    Checklist: persona split ✅, naming ✅, surface field + backfill ✅, tool scoping (no global fall-through; tools(ask) carries no authoring tools — asserted) ✅, withdraw tenant agents ✅. D4 left deferred per the issue.

    Note: several items were already done in main ahead of the ADR text (the ask rename; the resolver was already skill-scoped; build was already canonical+aliased). The cloud .framework-sha bump also required binding 18 control-plane script actions to satisfy framework's unrelated new action-script guard.

  2. xuyushun441-sys commented on Jun 22, 2026

    @xuyushun441-sys
    CollaboratorAuthor

    Keeping this as the single live tracker for ADR-0063/0064; closed #2165 (the near-duplicate follow-up) as superseded.

    The code split is done (this issue's checklist + #2181 + cloud#417). The one tail this was reopened for — the prose sweep / surface documentation — was the third-party skill-authoring contract skills/objectstack-ai/SKILL.md, which still described the old ADR-0040 unified data_chat assistant. That's fixed in #2194:

    • SKILL.md rewritten to the two surface-bound agents (ask/build); data_chat/metadata_assistant reduced to alias-table mentions only.
    • surface: 'ask'|'build'|'both' field + built-in skill affinities documented; tools = union of surface-compatible skills' tools (no global fall-through).
    • surface:'build' skills documented as inert on OSS — intentional tiering, with graceful build-intent degradation.
    • docs/adr/PRIORITIZATION.md stale 0040 row reconciled.

    After #2194 merges, the only outstanding item is D4 (deployment guardrail-floor), which remains deferred (no tenant agent to floor once withdrawal landed). Suggest closing this once #2194 is in and the D4 deferral is acknowledged.

  3. xuyushun441-sys commented on Jun 22, 2026

    @xuyushun441-sys
    CollaboratorAuthor

    All 13 checklist items are done; ticked above. Summary:

    Duplicate follow-up #2165 closed as superseded by this issue.

    D4 (deployment guardrail-floor schema) remains deferred — no tenant agent to floor once withdrawal landed; tracked in the audit (docs/audits/2026-06-ask-build-agent-development-assessment.md), not blocking.

    Closing — ADR-0063/0064 fully landed bar the deferred D4.

  4. hotlong commented on Sep 10, 2026

    @hotlong
    Contributor

    ⚠️ Closing not_planned — the premise of this card is falsified. PM session_01FGca3Gt5irhBoVcVwFfoVY, 2026-09-10T09:0xZ. Correction is on me, not on anyone who read it.

    This card said EnvSettingsRoutesPlugin is an orphan workaround that exists only because cloud#1963 req 6 forbade framework changes, and that the next host door should go through the framework's registerDomainHandler instead of copying it.

    The second half is wrong, measured on origin/main. objectstack dd2184a (#16741, merged 2026-09-08) built exactly that next host door — mountStorageRoutes, for kernels with no http-server — and its docblock names the settings bridge as the working precedent it followed, verbatim:

    The settings service already has a working answer to the same shape: the host mounts registerSettingsRoutes on its raw app and dispatches into the environment kernel's route table.

    It did not use registerDomainHandler, did not add a /storage dispatcher domain, and did not touch route-ledger.ts. So the shape this card called an orphan is the shape the framework adopted; the only thing #16741 changed is that the composition of the gates now lives inside the owning package rather than on the host's side, which is a refinement of the same pattern, not a replacement for it.

    ⇒ There is nothing to migrate and nothing to warn the next card away from. Leaving this card open would actively mis-route the next host door.

    Why I got it wrong: the checkout I read is pinned at 8b37a09 (2026-09-08T03:59Z), 288 commits behind origin/main; #16741 merged about two hours after that pin. Every framework reading in this card, and in the comment I posted on #1969 the same day, is accurate for that tree and stale for today's. See objectstack#17354 for the same correction on the framework side.

    ⛔ Do not reopen this as a "migrate the settings door" card without a fresh reading — as of origin/main today there is no divergence to close.


    Generated by Claude Code

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions