Repository navigation
docs(skills): a flow door's innerRefusal is the refusal any node met, not only a write's - #33390
Conversation
… not only a write's The api skill's flow-door paragraph described `details.innerRefusal` as a write refusal with a three-code list. A data node's refused read fills it too, and so does a `script` node's ambiguous or out-of-reach function name (`RESOURCE_CONFLICT`). The codes are now examples of any `ErrorCode` member. The code-handler table links the `script` node row to the automation skill's package rule instead of restating it. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J8VVAkdBkcn8QBYvVe7z6y
|
domain:skills#1 · os-project-manager · session_01FEkQ5pjSPT7ui2EUcunaVb Contract reviewServed-tier: Inputs: card #32379 (body and all five comments: triage 6784704236, claim 6787593131, Release 6807417751, claim 6881923473, os-dev-report 6882093316), PR #33390 (body, two-file list, net diff against merge base ① Derived judgments
② Semver level
③ Boundary flags
④ Design judgment
Findings:
Implemented-by: VERDICT: PASS Adopted by the seat 2026-11-14T18:36Z · isolated sub-agent at CONTRACT_REVIEW_TIER · Ruling-ref: Leehom card cmsg_01TenzsRopZj4jMbvjX8uz1XFhuiZmTH8VFgMmHRmpiGAb, option A, tapped 2026-11-14T15:37Z |
|
domain:skills#1 · os-project-manager · session_01FEkQ5pjSPT7ui2EUcunaVb 维护者速读
席位核对Verdict: ACCEPT, held for the maintainer · head
|
Requested by Leehom · project thread
Fixes #32379
domain:skills#1 · os-project-manager · session_01FEkQ5nPZFfbs98ogV2mAFM
Clause-②: no
Metadata-protocol: none
维护者速读
objectstack-api技能里流程入口400 FLOW_FAILED一段,原文把details.innerRefusal说成「节点的写入被拒」并只列三个错误码;现改为「节点遇到的拒绝」(数据节点的读或写、script节点的函数名),错误码改为举例并补上RESOURCE_CONFLICT。另在「apis:还是代码处理器」表格的script行加一个链接,指向 automation 技能里讲「到底运行哪个函数」的条目,不复述。script节点的函数名在本包范围内有歧义或只在依赖闭包外,流程入口答400 FLOW_FAILED,innerRefusal.code为RESOURCE_CONFLICT;按旧文按错误码分支的客户端会漏掉它。skills/objectstack-api/SKILL.md改 5 行、净增 1 行,外加一个 changeset;不动 schema、不动运行时;回滚即还原本 PR。skills/objectstack-api/SKILL.md第 360–363 行(innerRefusal 句),再看第 133 行(表格链接)。git diff origin/main -- skills/,预期只见上述两处:innerRefusal 句改为「a node met」并举RESOURCE_CONFLICT,表格script行多一个指向 objectstack-automation「Valid-but-silently-wrong」第 3 条的链接。skills/**):请批准或合并。What changes
skills/objectstack-api/SKILL.mdlines 360–363, the flow-door paragraph.innerRefusal?was "the{ code, message }a node's write was refused with,codein its wire spelling (UNIQUE_VIOLATION,VALIDATION_FAILED,PERMISSION_DENIED)". It now reads "the{ code, message }refusal a node met (a data node's read or write, ascriptnode's function name),codeanErrorCodemember in wire spelling (e.g.UNIQUE_VIOLATION,PERMISSION_DENIED,RESOURCE_CONFLICT)". The codes are examples now, not a set.skills/objectstack-api/SKILL.mdline 133, the "Choosing betweenapis:and a code handler" table. Thescriptnode row gains one link, "which one runs: objectstack-automation item 3", and restates nothing..changeset/32379-api-flow-inner-refusal-any-node.md:'@objectstack/skills': patch, carrying both declaration lines.This resumes the released commit
ab838308(branchclaude/project-thread-xb2225, Release comment 6807417751) and mergesorigin/main6538ba48. Every claim the commit makes was re-read on thatmain(below); none moved, so the text is unchanged.Why
Each claim, read on
origin/main6538ba48:scriptnode's function-name refusal fillsinnerRefusalwithRESOURCE_CONFLICT.packages/services/service-automation/src/builtin/screen-nodes.ts:651-660: whenengine.resolveFunctionthrows a package-scoped refusal, the node returnscode: 'RESOURCE_CONFLICT'plusrefusalCarriedBy(err). Pinned at the flow door bypackages/qa/dogfood/test/bare-name-one-holder-request-family.dogfood.test.ts:280-298([400, 'FLOW_FAILED'],details.innerRefusal.code === 'RESOURCE_CONFLICT') and in-engine bypackages/services/service-automation/src/flow-function-package-scope.test.ts:134(both from PR fix(service-automation)!: a flow script node runs its function by package (ADR-0150 D3) #32257).refusalCarriedByis called by all four data-node catch arms inpackages/services/service-automation/src/builtin/crud-nodes.ts(get_record:669, and :831, :947, :1026 for the three writes). It carries any declared 4xx throw (inner-refusal.ts:86-102).codeis anErrorCodemember.FlowInnerRefusalSchema.codeisErrorCode(packages/spec/src/api/automation-api.zod.ts:361-366).skills/objectstack-automation/SKILL.md:230is the heading## Valid-but-silently-wrong (passes build, fails at runtime), and item 3 (:262-275) states the package rule for which function ascriptnode runs (landed in PR docs(skills): teach the script node's package rule in the automation skill #32377). The anchor follows the formskills/objectstack-data/SKILL.md:221already uses for another heading in that skill.Acceptance notes
skills/sweep (git grepforinnerRefusalandFLOW_FAILED): this paragraph is the only skill text that teachesinnerRefusal. Noevals/*.jsonmentions it, so no eval was made false..describeonFlowFailureDetailsSchema.innerRefusal(packages/spec/src/api/automation-api.zod.ts:640-642, mirrored incontent/docs/references/api/automation-api.mdx:389and:1140) still says "the refusal a node's write met". It is spec prose, outside this card's surface (carrier: none).Verification
Head
9adabd41, baseorigin/main6538ba48.Line and token budget (skills/**)
skills/objectstack-api/SKILL.md: 431 to 432 lines, 20628 to 20841 bytes; token ratchet 5152 to 5206 (ceiling 6314, headroom 1108). No ceiling moved.skills/*/SKILL.md(11 files): 4602 to 4603 lines. Bundle total (whole shipped tree): 244310 to 244364 tokens.node scripts/pm/check-skill-line-ratchet.mjs: exit 0.node scripts/check-skills-token-ratchet.mjs: exit 0.Derived gates
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 46 families for the two paths. Each was run on head9adabd41, exit code captured before any pipe (record: project filepm-orders/skills/32379-gates-ran.txt):check-adr-0087-registration(scan and--self-test),check-changeset-no-major,check-empty-changeset(scan and--self-test),check-skills-token-ratchet(scan and--self-test),@objectstack/spec check:skill-docs,check:changeset-gate-self-tests,check:doc-authoring,check:nul-bytes,check:pm-governed-merges,check:published-files,check:skill-compatibility,check:skill-frame-sync,check:skill-identifier-liveness,check:skill-links.@objectstack/lint check:doc-formula-expressionsexit 0, after building the@objectstack/lint...closure under the verify lock (VERDICT command-exit 0, 67s).check:dts-closureandcheck:sourcemap-no-sources-contentexit 0 over the 5 packages that build left indist/only; CI builds every package and runs them in full.dist/):check:dual-build-cjs-loads,check:lean-entry-closure. No package source is touched, so no full build was paid locally.--ranreconciliation: "46 derived famil(ies) accounted for — 44 run, 2 NOT-MEASURED (2 DERIVED from a recorded exit 3)".Tier and governed readings
dispatch-gates --tier: MANDATORY contract-review tier (skills/**, clause ①, the published catalog); no one-line exit for this surface.node scripts/pm/check-governed-merges.mjs --branch claude/project-thread-co1yph: exit 3, GOVERNED, landing tier H (人合). 1 of 2 paths on the register (skills/**); the changeset is not on it. Size +15 / -4, under the 3000 threshold.🤖 Generated with Claude Code
https://claude.ai/code/session_01FEkQ5nPZFfbs98ogV2mAFM