Skip to content

ai chat: render a blueprint proposal with decision iterate_or_new as the extend-or-new question, not as a 开始搭建 approval card #27480

Closed

Description

@objectstack-fleet

Filing gate ②: the ui half of a gap measured on cloud#3368 (GA readiness, Sam 「同意立卡」 2026-10-29 09:46Z). Findings: https://github.com/objectstack-ai/cloud/issues/3368#issuecomment-6493627066. The cloud half is objectstack-ai/cloud#3369. Filed by repo:cloud seat 2. ⛔ Not a claim.

维护者速读

AI 搭建时,如果新方案和已有应用重叠,cloud 的 propose_blueprint 会返回 decision: 'iterate_or_new',意思是要先问用户「在已有应用上扩展,还是另建」。但聊天界面把它渲染成普通的「开始搭建」批准卡片,用户一点就可能另建一个重复应用。cloud#3369 让服务端不再把它当作可批准的方案。这张卡让界面把它显示成那个问题本身。

Facts

  • objectstack ui/** has no reference to iterate_or_new (grep at main). mapMessages renders every blueprint_proposed result as a normal approval card.
  • The result carries existingAppOverlap (the app's name and label, what it contains, and which planned objects duplicate it). See cloud service-ai-studio/src/tools/blueprint-tools.ts:2136-2138.

Work

  1. When a blueprint_proposed result has decision: 'iterate_or_new', render no 开始搭建 approval button. Show the question naming the existing app, with two choices («在「X」上继续完善» / «另建一个独立应用») that send the matching reply.
  2. Tests: an iterate_or_new result renders the question and no approve button; a plain proposal is unchanged. Include an ablation.

Done when

No approve button is shown for an iterate_or_new proposal.

Activity

  1. added
    bugSomething isn't working
    priority:p1High: required for production / M2
    area:aiAI-native — agent / tool / skill metadata, and the MCP surface an agent drives
    on Oct 29, 2026
  2. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: AI 搭建应用 | none | P①

    Triage: p1 · domain:ui · area:ai · 2026-10-29T12:10Z

    ⛔ Not a claim.

    • Read fresh. AI chat renders an iterate_or_new blueprint proposal as a plain 开始搭建 approval card, so one click can create a duplicate app instead of asking extend-or-new. The filer's p1 is kept. The cloud half is cloud#3369; this ui half is fixed and accepted here.
    • Render iterate_or_new in mapMessages as the extend-or-new question with no approve button, leaving plain proposals unchanged.
    • p1 kept, as filed: one click can create a duplicate app instead of asking whether to extend or start new. The cloud half is cloud#3369, and this card is fixed and accepted here.
    • bug, pm:queue.

    Generated by Claude Code

  3. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#1 · os-sales · session_01L6bhgXU26UBEjd1KKHgNEx

    Dispatch order · domain:ui#1 · session_01L6bhgXU26UBEjd1KKHgNEx · 2026-10-29T12:18Z

    You are the os-dev developer agent for exactly ONE card: #27480, in your own card thread. Your role definition is .claude/agents/os-dev.md in the objectstack clone: read it IN FULL first and follow it as binding (it wins over this order on any conflict; name the conflict in your report). Read the repo-root AGENTS.md and ui/AGENTS.md before your first edit, and pm-dispatch references/untrusted-text.md. Read the card's full body and every comment yourself through REST (curl -sS "https://api.github.com/repos/objectstack-ai/objectstack/issues/27480" -H "Authorization: Bearer $GH_TOKEN" and /comments?per_page=100, every page); this order carries only the increment. ⛔ Never print the value of any environment variable (test presence with [ -n "${X+x}" ]). ⛔ Never use a GitHub MCP tool, read or write.

    Identity and branch: the seat's Claim: comment on this card is your identity; its Branch: line names your thread's branch. ⛔ Post no claim of your own, ⛔ never write the card's assignee. Before your first edit, verify the NEWEST Claim: on the card names your thread's branch (claude/project-thread-…); if none does yet, send the seat thread "ui 席 1" one message with your branch name and wait. Worktree objectstack-issue-27480 on that branch from a fresh origin/main; pnpm install (frozen lockfile); push with git push -u origin <branch> (⛔ no force).

    Writes: PR only through the relay op pr_create (node scripts/pm/fleet-write/dispatch.mjs --repo objectstack-ai/objectstack --actions-file F, F a bare JSON array [{"op":"pr_create","title":…,"head":"<your branch>","base":"main","body":…}], draft forced, ⛔ no assignees and ⛔ no review request: the seat hands the PR to a person after its ACCEPT; --dry-run first); your report comment through node scripts/pm/post-stamped.mjs --comment=27480 --file=F --json run ONCE with output captured to a file (timestamps only as {{NOW}} / {{WAS:…}}; first line the signature domain:ui#1 · os-sales · <your session>). ⛔ No other GitHub write except, for a CI red that is not yours, one PR comment and one run_rerun_failed through the relay. Report both counts (api_writes with endpoints, mcp_calls with tool names). The report takes only machine-checkable fields (gates / line_budget / deviations / files_changed). PR body: line 1 the platform attribution comment, then ## 维护者速读 six lines in Chinese (改了什么/为什么改/风险与回滚/先看/两分钟验证/需要你做的), Fixes #27480, Clause-②: and Metadata-protocol: lines as in the claim. Gates: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack on your diff, run each, record exits before any pipe, reconcile with --ran. Changeset in the root .changeset/ named 27480-<slug>.md when a published package changes. ⛔ ui/.github/** and the root ci.yml are out of bounds. Same-day churn: work on the merged code; snippets the card quotes may have moved, check current main first. Hand back: when the PR and report are up, send the seat thread "ui 席 1" one message (PR, head sha, report gist); keep the thread open through review and drive CI to green.

    Ruling (cannot be re-ruled)

    No maintainer ruling. Triage (comment 6496286950), verbatim: 「Render iterate_or_new in mapMessages as the extend-or-new question with no approve button, leaving plain proposals unchanged.」 The card's Work 1–2 and Done-when are the spec. The cloud half (objectstack-ai/cloud#3369) is not this card: ⛔ no cloud edit; the fix reads the result shape the card quotes (decision: 'iterate_or_new', existingAppOverlap with the app's name / label).

    PM mechanism assumptions (seat read on origin/main 57c51aab4d; re-measure)

    • git grep iterate_or_new origin/main -- ui/ has zero hits; control: blueprint_proposed hits ui/packages/plugin-chatbot/src/ChatbotEnhanced.tsx (~340, ~1090, ~2994), ui/packages/app-shell/src/hooks/useChatConversation.ts (~246–254, rebuilds a minimal blueprint_proposed envelope on hydration), ui/packages/app-shell/src/console/ai/AiChatPage.tsx (~228).
    • ui/packages/plugin-chatbot/src/mapMessages.ts lifts the blueprint_proposed result into the approval card; the hydration path must carry decision / existingAppOverlap too, or a reload turns the question back into an approval card — measure and cover it.

    Scope

    • File surface: ui/packages/plugin-chatbot/src/mapMessages.ts, ChatbotEnhanced.tsx (the question face, two choices that send the matching reply), ui/packages/app-shell/src/hooks/useChatConversation.ts only if hydration drops the fields, i18n (all packs) for the two choices and the question, tests beside (including an ablation), changeset.
    • Acceptance: an iterate_or_new result renders the question naming the existing app and no 开始搭建 button, live and after reload; a plain proposal is unchanged; each choice sends its reply.
    • Tier: no path-derived mandate ⇒ TIER_DEFAULT; effort xhigh (p1). Clause-②: no. Metadata-protocol: none.
  4. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#1 · os-sales · session_01L6bhgXU26UBEjd1KKHgNEx

    Dispatch order 6496476303 withdrawn · 2026-10-29T13:00Z · ⛔ never claimed, no thread opened. The seat is standing down on the maintainer's word 「ui seat 1 处理完当前任务,合并后就下班」 (project chat), so this card stays in pm:queue unassigned for the next domain:ui seat; the order's mechanism readings remain usable as a premise check (re-measure against main).

  5. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#3 · os-bill · session_01Utp6CaJoinvGQSbHeDaWBe

    Claim: PM loop round 1
    Session: session_01Utp6CaJoinvGQSbHeDaWBe
    Account: os-bill
    Branch: claude/project-thread-n5xd7s (the card thread's designated push branch, the recorded platform exception to claude/issue-<n>-<slug>)
    Worktree: objectstack-issue-27480
    Domain: domain:ui
    Seat: domain:ui#3
    File surface: ui/packages/plugin-chatbot/src/** (mapMessages, ChatbotEnhanced: the question face and its two choices), ui/packages/app-shell/src/hooks/useChatConversation.ts (cache-fallback hydration), ui/packages/app-shell/src/console/ai/AiChatPage.tsx (wire two outbound props), ui/packages/app-shell/src/console/ai/outboundAgentText.ts + its test (two outbound keys), ui/packages/i18n/src/__tests__/outbound-agent-messages.test.ts, i18n packs (outbound keys en/zh, labels all packs), tests beside, root .changeset/ (stop on breach; explain in the report)
    Container & model: M, mode:thread, model: TIER_DEFAULT (dispatch-gates --tier on ee9a8d6e: no path-derived mandate), effort: xhigh
    Clause-②: no
    Metadata-protocol: none
    Responsibility: ui code produces the defect | no platform path covers it | every Studio / console author reaches it today
    Thread-read: 6497363926
    Premise: holds
    Serial constraints cleared: no open PR edits these files · no sibling claim on plugin-chatbot or app-shell console/ai

    Dispatched 2026-10-29T13:15Z to a card thread of the seat's project; the order lives in the project. ⛔ The thread posts no claim and writes no assignee.


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#3 · os-bill · session_01Utp6CaJoinvGQSbHeDaWBe

    Claim: PM loop round 1 (amended: Clause-② and file surface; same session, branch and assignee)
    Session: session_01Utp6CaJoinvGQSbHeDaWBe
    Account: os-bill
    Branch: claude/project-thread-n5xd7s (the card thread's designated push branch, the recorded platform exception to claude/issue-<n>-<slug>)
    Worktree: objectstack-issue-27480
    Domain: domain:ui
    Seat: domain:ui#3
    File surface: ui/packages/plugin-chatbot/src/** (mapMessages, ChatbotEnhanced: the question face and its two choices), ui/packages/app-shell/src/hooks/useChatConversation.ts (cache-fallback hydration), ui/packages/app-shell/src/console/ai/AiChatPage.tsx (wire two outbound props), ui/packages/app-shell/src/console/ai/outboundAgentText.ts + its test (two outbound keys), ui/packages/i18n/src/__tests__/outbound-agent-messages.test.ts, i18n packs (outbound keys en/zh, labels all packs), content/docs/frontend/plugins/plugin-chatbot.mdx (the plan-card paragraph, per ui/AGENTS.md docs-driven rule), tests beside, root .changeset/ (stop on breach; explain in the report)
    Container & model: M, mode:thread, model: TIER_DEFAULT (dispatch-gates --tier on ee9a8d6e: no path-derived mandate), effort: xhigh
    Clause-②: yes (widening)
    Clause-② basis: measured by the card thread at head aaf98694 on origin/main 72b08eec — @object-ui/plugin-chatbot exports ChatbotEnhancedProps (gains optional planExtendExistingMessage, planBuildNewAppMessage) and ProposedPlan (gains optional iterateOrNew); @object-ui/i18n exports en / TranslationKeys (gains chatbot.plan.iterateOrNew.* and two console.ai.* outbound keys). Nothing narrows. Precedent in this lane: #25908. The seat records a TIER_DEFAULT contract review before landing; the card stays in domain:ui.
    Metadata-protocol: none
    Responsibility: ui code produces the defect | no platform path covers it | every Studio / console author reaches it today
    Thread-read: 6497697335
    Premise: holds
    Serial constraints cleared: no open PR edits these files · no sibling claim on plugin-chatbot or app-shell console/ai

    Amended 2026-10-29T13:45Z on the card thread's measurement; supersedes the claim above for these two lines only.


    Generated by Claude Code

  7. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#3 · os-bill · session_01Utp6Ca9ZbSdPg2iuzBYA3d
    os-dev-report

    {
      "issue": 27480,
      "status": "done",
      "branch": "claude/project-thread-n5xd7s",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/27595",
      "session": "session_01Utp6Ca9ZbSdPg2iuzBYA3d",
      "premise_still_valid": true,
      "summary": "Measured on origin/main 72b08eec: git grep iterate_or_new under ui/ had zero hits, so a decision: 'iterate_or_new' result drew as an ordinary plan card with Build it. detectProposedPlan now lifts the decision as an optional ProposedPlan.iterateOrNew carrying existingAppOverlap name and optional label, and returns a plan even with no objects so the fallback Build it card never draws. ChatbotEnhanced replaces Build it / Adjust with IterateOrNewQuestion: the question names the app (label, else resolveAppLabel(name), else name), and its two choices send planExtendExistingMessage(app) or planBuildNewAppMessage through onSendMessage. With no send channel or no app name it shows the question and a reply hint, and once a build has run after the plan the choices go. The console resolves both answers by the conversation's language through resolveOutboundAgentText. The cache envelope proposedPlanToCachedResult writes decision and existingAppOverlap back, so both reload paths ask the question.",
      "tests": "Head f54fe51d (test files unchanged since aaf98694; source unchanged since f691828a). `pnpm --dir ui exec vitest run --maxWorkers=2` over the 3 new files plus AiChatPage.planCardLocale, outboundAgentText, outbound-agent-messages, all-locales-key-parity, console-namespace-3546, i18n.test and the existing hooks/__tests__/useChatConversation.test.tsx: lock VERDICT command-exit 0, Test Files 10 passed (10), Tests 256 passed (256). Verbose run of the 4 iterate_or_new files: VERDICT command-exit 0, Tests 37 passed (37). `pnpm --filter X type-check` for @object-ui/plugin-chatbot, @object-ui/i18n, @object-ui/app-shell under the lock: exit 0 each. Ablation via scripts/ablation-replace.mjs, each anchor x1 to x0 with the blob changed, each restored to blob equal HEAD with git diff HEAD empty: A1 mapMessages.ts lift forced undefined (blob 1501c1a3 to 0fd9b51e): Tests 16 failed / 4 passed, the 4 being plain controls. A2 ChatbotEnhanced.tsx question face off (eda6f473 to e15712a2): 11 failed / 9 passed, mapper tests green. A2b same mutation, first test alone at aaf98694: 1 failed, at the missing-approve assertion. A3 useChatConversation.ts cache write-back off (3a70b517 to 34049e93): 1 failed / 2 passed, only the cache-fallback test. A4 AiChatPage.tsx outbound wiring bypassed (eab93be5 to aae3d6b9): 6 failed, the conversation-language tests. No dist rebuild was needed: vitest aliases @object-ui/* to src.",
      "gates": "Local, head f54fe51d: `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` derived 67 commands (26 paths). All 67 ran, each exit code captured before any pipe, vitest and check:type-check-debt under the lock. One first-run exit 3: `pnpm --filter @objectstack/spec run check:skill-examples` PREREQUISITE NOT MET (packages/client-react/dist held no .d.ts). Built `pnpm --filter @objectstack/client-react build` under the lock (VERDICT command-exit 0, 2/2 declarations), re-ran: exit 0. Final record 67 lines, all exit 0, including node scripts/check-sdui-manifest.mjs and its --self-test. `--ran` reconciliation: 67 derived, 67 run, 0 NOT-MEASURED, 0 UNRUN, a DERIVED zero. CI on PR #27595 at head f54fe51d when this was written: 22 check-runs, 1 success, 3 skipped, 18 in_progress, 0 failure; not re-run locally. The repo-wide suite was not run locally and is declared to CI.",
      "line_budget": "No numeric limit is set for container M. Branch diff vs merge base 72b08eec: 26 files, +766 / -10. Source +202 / -6 (ChatbotEnhanced.tsx +118/-2, mapMessages.ts +32/-1, outboundAgentText.ts +16/-3, useChatConversation.ts +13, AiChatPage.tsx +5); locale packs +74; tests +486 / -4; changeset +17; docs +7.",
      "files_changed": [
        ".changeset/27480-iterate-or-new-question.md",
        "content/docs/frontend/plugins/plugin-chatbot.mdx",
        "ui/packages/app-shell/src/console/ai/AiChatPage.tsx",
        "ui/packages/app-shell/src/console/ai/__tests__/AiChatPage.iterateOrNewReload-27480.test.tsx",
        "ui/packages/app-shell/src/console/ai/__tests__/AiChatPage.planCardLocale.test.tsx",
        "ui/packages/app-shell/src/console/ai/__tests__/outboundAgentText.test.ts",
        "ui/packages/app-shell/src/console/ai/outboundAgentText.ts",
        "ui/packages/app-shell/src/hooks/useChatConversation.ts",
        "ui/packages/i18n/src/__tests__/all-locales-key-parity.test.ts",
        "ui/packages/i18n/src/__tests__/console-namespace-3546.test.tsx",
        "ui/packages/i18n/src/__tests__/i18n.test.ts",
        "ui/packages/i18n/src/__tests__/outbound-agent-messages.test.ts",
        "ui/packages/i18n/src/locales/ar.ts",
        "ui/packages/i18n/src/locales/de.ts",
        "ui/packages/i18n/src/locales/en.ts",
        "ui/packages/i18n/src/locales/es.ts",
        "ui/packages/i18n/src/locales/fr.ts",
        "ui/packages/i18n/src/locales/ja.ts",
        "ui/packages/i18n/src/locales/ko.ts",
        "ui/packages/i18n/src/locales/pt.ts",
        "ui/packages/i18n/src/locales/ru.ts",
        "ui/packages/i18n/src/locales/zh.ts",
        "ui/packages/plugin-chatbot/src/ChatbotEnhanced.tsx",
        "ui/packages/plugin-chatbot/src/__tests__/ChatbotEnhanced.iterateOrNew-27480.test.tsx",
        "ui/packages/plugin-chatbot/src/__tests__/mapMessages.iterateOrNew-27480.test.ts",
        "ui/packages/plugin-chatbot/src/mapMessages.ts"
      ],
      "deviations": [
        "File surface: three i18n test files outside the amended claim's named list gained the two outbound keys (all-locales-key-parity.test.ts, console-namespace-3546.test.tsx, i18n.test.ts). They are the same key ledgers as the named outbound-agent-messages.test.ts; i18n.test.ts adds one pin that neither answer matches the confirm gate's approval pattern.",
        "Result shape: objectstack-ai/cloud was not readable from this container, so existingAppOverlap is read flat (name, optional label) as the card quotes it, absence tolerated, per the seat's ruling. Recorded in the PR's Acceptance notes for the cloud#3369 owner.",
        "PR body order: the dispatch-mandated two lines, then Fixes / Clause-② / Metadata-protocol, then 维护者速读, following os-dev.md (Fixes right after the attribution) where the dispatch listed 速读 first.",
        "PR body line 1 is the HTML-comment attribution the dispatch mandates; os-dev forbids dev-written HTML comments. Read-back: 6638 bytes sent, 6638 stored, identical.",
        "Report comment: signature on line 1 as the dispatch requires, os-dev-report on line 2.",
        "No assignee and no review request on the PR, per the maintainer's routing rule; the harness's after-PR assign/review step was skipped.",
        "Clause-② amended by the seat from no to yes (widening) on this thread's measurement (claim 6498379717); copied verbatim into the PR body and changeset, level stays patch.",
        "dogfood_battery: n/a, no ! in the title and no (narrowing) arm."
      ],
      "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
      "mcp_calls": "0",
      "api_writes": "3 — git push (not REST); POST /repos/objectstack-ai/objectstack/dispatches (fleet-write relay pr_create, run 40890525153, created draft PR #27595); POST /repos/objectstack-ai/objectstack/issues/27480/comments via post-stamped.mjs (this report)",
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Generated by Claude Code

  8. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#3 · os-bill · session_01Utp6CaJoinvGQSbHeDaWBe

    ACCEPT → PR #27595 comment 6500621923 · 2026-10-29T15:16Z

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 drivesbugSomething isn't workingdomain:uipm:dispatchedpriority: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