Repository navigation
feat(spec): CloneFlowResponseSchema declares an optional data.noticeCode beside notice - #29779
Conversation
…ode beside notice A stable code naming the clone notice sentence, so a client can show its own translation and fall back to the English notice for an unknown or absent code. Claude-Session: https://claude.ai/code/session_01JQwxbWyGo9rhjNEzeo5Ujt Co-authored-by: Claude <noreply@anthropic.com>
…eCode changeset Claude-Session: https://claude.ai/code/session_01JQwxbWyGo9rhjNEzeo5Ujt Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 1 package(s): 1 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 2 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 168 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 019790643f1f1b0e503b71d2b007ac36b29ccc2d && git checkout 019790643f1f1b0e503b71d2b007ac36b29ccc2d
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 7ba8b11f52215f945ef1fd417d38b1fb00d8c20e be18e3d1b06da2c7fbdadcb3c1382dd046c449ba && git checkout -B drift-repro 7ba8b11f52215f945ef1fd417d38b1fb00d8c20e && git merge --no-ff be18e3d1b06da2c7fbdadcb3c1382dd046c449ba
node scripts/docs-audit/affected-docs.mjs --json 7ba8b11f52215f945ef1fd417d38b1fb00d8c20e
|
|
domain:server#1 · os-warren · session_01JQwxbXsK9j25sd7eVwW96G Contract-review-claim: session_01JQwxbXsK9j25sd7eVwW96G · head be18e3d · 2026-11-03T04:20Z |
|
domain:server#1 · os-warren · session_01JQwxbXsK9j25sd7eVwW96G Contract reviewServed-tier: ① Derived judgments
② Semver levelChangeset
③ Boundary flags
④ Design judgment
Implemented-by: VERDICT: PASS |
|
domain:server#1 · os-warren · session_01JQwxbXsK9j25sd7eVwW96G 席位核对ACCEPT ·
|
Requested by Warren · project thread
Fixes #29758
Clause-②: yes (widening)
Metadata-protocol: none
This is the contract-first half of #29727 and unblocks it: the server half (sending the code from the flow clone door) stays on #29727.
维护者速读
notice旁新增可选字段noticeCode,用一个稳定代码标识这句提示。notice是服务端写死的英文句子,控制台无从得知是哪一句,中文界面只能原样显示英文;有了代码,控制台可以换成自己的译文。notice仍必填、仍是英文兜底;回滚即撤掉该键,无数据迁移。packages/spec/src/api/automation-api.zod.ts(CloneFlowResponseSchema的noticeCode与其说明),packages/spec/src/api/automation-api.zod.test.ts(四条 pin),.changeset/29758-clone-flow-notice-code.md。pnpm --filter @objectstack/spec exec vitest run src/api/automation-api.zod.test.ts,预期 72/72 通过。noticeCode在否决窗口内,有异议请在本 PR 说)。What changes
CloneFlowResponseSchema.data(packages/spec/src/api/automation-api.zod.ts) declaresnoticeCode: z.string().optional()besidenotice, described as a stable code naming thenoticesentence: a client maps a code it knows to its own translated sentence and falls back tonoticeverbatim for an unknown or absent code. No code values are enumerated; the vocabulary is the server's (runtime: the flow and permission-set "New similar" clone notices carry a code, so the Console can translate them (zh-CN shows English today) #29727).noticeand its describe are unchanged. The schema's TSDoc gains one sentence saying the same.noticeCode, the seat's call under the veto window. A key namedTHING+Codefor the code of a sibling sentence followsdeclaredCodeinpackages/spec/src/api/contract.zod.ts.content/docs/references/api/automation-api.mdx(viagen:docs) is the only artefact the member moves.check:authorable-surface,check:api-surface,check:export-origins,check:declaration-mapandcheck:strictness-ledgerstayed green with no regeneration: the authorable-surface shard listsapi/CloneFlowResponse:dataand nothing below it, and no export was added.@objectstack/specpatch, not the minor the dispatch named.Metadata-protocol: none(a REST answer shape is nothing a metadata author writes, and no authorable-surface shard moved), andscripts/check-changeset-no-major.mjsrefuses aminorbesidenone; a non-protocol widening shipspatchand keepsClause-②: yes (widening).@objectstack/clientgets no entry:automation.clone()returnsCloneFlowResponse['data']imported from@objectstack/spec(a dependency, external to the client's tsup build), so its emitted types do not change.Why
The Console prints
data.noticeverbatim, so the flow "New similar" notice shows English under zh-CN (#29706 row 1). Nothing in the answer named which sentence it was. A code beside it lets the Console translate it, contract-first, before the server sends one.Tests
packages/spec/src/api/automation-api.zod.test.ts, newdescribe('CloneFlowResponseSchema — data.noticeCode names the notice sentence'):noticeCodebesidenoticeand keeps it on the parsed value;noticeCodestill parses;noticeis still required (one issue,invalid_typeatdata.notice);noticeCodeis refused (one issue,invalid_typeatdata.noticeCode).Ablation, once, on the committed head
d419dc32throughscripts/ablation-replace.mjs(the test imports./automation-api.zodfrom source, so no dist leg): renaming the key tonoticeCodeAblatedlanded on disk (anchor 1 → 0, blob767587bb7ef0→c06b7927ece5); pins 1 and 4 went red (2 failed, 70 passed); restored to blob767587bb7ef0withgit diff HEADempty.Acceptance notes
Consumers of
CloneFlowResponse, read onorigin/mainc9c68288:packages/client/src/index.tsautomation.clone()returnsCloneFlowResponse['data']: gains the optional key through the type, no edit.packages/runtime/src/domains/automation.ts(the clone handler) answers{ flow, packageId, notice: FLOW_CLONE_NOTICE }frompackages/runtime/src/flow-clone.ts: unchanged here, and still parses (the key is optional). Serving the code is runtime: the flow and permission-set "New similar" clone notices carry a code, so the Console can translate them (zh-CN shows English today) #29727.packages/runtime/src/route-ledger.tsnamesCloneFlowResponseSchemafor the clone row; its note spellsdataas{ flow, packageId, notice }, which runtime: the flow and permission-set "New similar" clone notices carry a code, so the Console can translate them (zh-CN shows English today) #29727 updates when it serves the code.packages/runtime/src/domains/automation-flow-clone-custom-package.test.tsparses each answer through the schema: still green by construction (optional key).ui/packages/app-shell/src/views/studio-design/AutomationsPillar.newSimilar-28567.test.tsxnames the schema in a comment only. The Console mapping is Studio: zh-CN first screens stop mixing English: the clone notice, the new package form, the flow rail group #29706.packages/metadata-protocol/src/protocol.tsis not touched (freeze).Verification
All readings on head
be18e3d1(objectstack-ai/objectstack, merge basec9c68288).Local runs
pnpm --filter @objectstack/spec buildunder the verify lock: VERDICT command-exit 0.pnpm --filter @objectstack/spec check:generated: first run named one stale artefact (content/docs/references/**), regenerated withgen:docs; re-run "All 14 generated artifacts are up to date", exit 0.pnpm --filter @objectstack/spec typecheckunder the lock: VERDICT command-exit 0.pnpm --filter @objectstack/spec exec vitest run --maxWorkers=2(the whole spec suite) under the lock: VERDICT command-exit 0, Test Files 892 passed (892), Tests 25326 passed, 1 todo.pnpm lint(eslint . --no-inline-config): exit 0.node scripts/pm/dispatch-gates.mjs --commands: 102 derived families. Run with exit codes recorded before any pipe, then--ran: "102 derived famil(ies) accounted for — 101 run, 1 NOT-MEASURED". Six first exited 3 on missing builds; afterturbo run buildfor@objectstack/lint...,@objectstack/objectql,@objectstack/formulaand@objectstack/client-react..., five re-ran at exit 0. NOT MEASURED:check:dual-build-cjs-loads(needs every package's dist; left to CI).node scripts/check-changeset-no-major.mjs --base c9c68288d --event EVENTwith this body: exit 0, "LEVEL AXIS: clause-② yes (widening) and metadata-protocol none … a non-protocol change at patch".Human Minimum
packages/specholds no runtime logic.pnpm lintpasses.main, one pull request.packages/spectouched: its generated artifacts are regenerated and committed.content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.Card thread session
session_01JQwxbWyGo9rhjNEzeo5Ujt, dispatched bydomain:server#1.🤖 Generated with Claude Code
https://claude.ai/code/session_01JQwxbWyGo9rhjNEzeo5Ujt
Generated by Claude Code