Repository navigation
docs(skills): the automation skill teaches the mail option formatter for a notice's select label and the active-member rule for a user target; the docs page gains organization-authored assignment rules - #30866
objectstack-fleet[bot] wants to merge 4 commits into
Conversation
…abel and the active-member rule for a user target The automation skill's notify section says an option label in a notice is written in the mail template as the option formatter, which prints each recipient's language, never label() in templateData (evaluated once per run, before fan-out); its assignment-rules section says a user target holds the row only while an active member of its organization. Eval 15 grades the notice case. The queues-and-assignment-rules docs page gains the organization-authored sys_assignment_rule rules beside the declared ones: evaluated first, by sort_order then name, first match wins, a failed read routes nothing, and the active-member rule. Paid inside SKILL.md by deleting the CRM Automation Blueprint section and two restatements; the token ceiling re-locked at the measurement. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9qibxujehvWJcGRXMYv7f
|
domain:skills#2 · os-tesla · session_01L9qibz5RLVEYDFco93jZ7u Contract reviewServed-tier: ① Derived judgments
② Semver level
③ Boundary flags
④ Design judgment
Deletions that paid for the growth, each checked for a surviving home:
No rule is left without a home. No must-fix, no should-fix. Implemented-by: VERDICT: PASS |
…, re-ordered or relabelled, not renamed The save guard re-judges a patch that touches name (one of the judged columns), so only the label, description, order and active flag escape the re-judgement. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9qibxujehvWJcGRXMYv7f
|
domain:skills#2 · os-tesla · session_01L9qibz5RLVEYDFco93jZ7u 维护者速读
席位意见:契约复审 PASS,无必改、无建议修改。席位在文档里查出一处错("可以改名",实际改名会被重新校验),已改。可以批准。 席位核对ACCEPT · seat
|
…-esfn9k # Conflicts: # skills/objectstack-automation/SKILL.md
|
domain:skills#2 · os-tesla · session_01L9qibz5RLVEYDFco93jZ7u Contract reviewServed-tier: This is a DELTA record. It builds on the record at ① Derived judgments
② Semver level
③ Boundary flags
④ Design judgmentOnly the two moved surfaces are re-judged; the earlier ④ holds for everything else.
No must-fix, no should-fix. Implemented-by: VERDICT: PASS |
|
domain:skills#2 · os-tesla · session_01L9qibz5RLVEYDFco93jZ7u 维护者速读
席位意见:契约复审 PASS,无必改、无建议修改。席位在文档里查出一处错("可以改名",实际改名会被重新校验),已改。与 #30831 的冲突已解决,两边内容都保留,增量复审通过。可以批准。 席位核对ACCEPT · seat
|
Requested by Tesla · project thread
Fixes #30731
Fixes #30826
Clause-②: no
Metadata-protocol: none
domain:skills#2 card thread (dev session
session_01L9qibxujehvWJcGRXMYv7f, seat sessionsession_01L9qibz5RLVEYDFco93jZ7u) · branchclaude/project-thread-esfn9k(the fold thread's designated branch, named in the Claims 6678887018 on #30731 and 6678901809 on #30826) · baseorigin/main677d542a.维护者速读
skills/objectstack-automation/SKILL.md)新增两句:①notify节——通知里要印选项标签,写在邮件模板里用{{ stage | option:opportunity.stage }}(按每个收件人的语言印),option只有邮件模板认(行内title/message拒收),⛔ 不用templateData里的label()(每次运行只算一次、在收件人扇出之前);② 「Assignment rules」节——assignTo: { type: 'user' }指定的人只在仍是该组织的在职成员时才拥有记录,否则记录无主落地。eval 15 新增通知用例。文档页automation/queues-and-assignment-rules的「Declare an assignment rule」节新增组织自建规则(sys_assignment_rule):先于应用声明的规则求值、按sort_order再按名字、首个命中生效、组织规则读不到就不路由、user目标的在职成员规则、保存时校验哪些字段。optionformatter prints a select value as its option label in the recipient's language #30727 + fix(plugin-email): an option hole prints the option label in each recipient's language #30781 的邮件option格式化器;feat(objectql,plugin-sharing): an organization authors its own assignment rules as sys_assignment_rule records #30760 的组织自建分派规则),技能和文档还没教,照技能写通知的 agent 会去templateData里写label(),要么保存被拒,要么所有收件人同一种语言;读文档的作者仍以为分派规则只有声明式、user目标永远拥有记录。skills/objectstack-automation/SKILL.md的notify节新段与「Assignment rules」改行(措辞是否与main上的渲染行为一致);②content/docs/automation/queues-and-assignment-rules.mdx新增三段(与packages/objectql/src/assignment-rules.ts头注释逐条对照);③ 删掉的「CRM Automation Blueprint」节。node scripts/check-skills-token-ratchet.mjs | grep objectstack-automation/SKILL.md预期6448 tokens (ceiling 6448; headroom 0);pnpm check:skill-identifier-liveness预期退出 0。skills/**)——席位契约复审通过后,由 os-zhuang 批准/入队。What changes
#30731 —
skills/objectstack-automation/SKILL.md,notifysection. One paragraph after thenotifyconfig block: an option label in a notice is{{ stage | option:opportunity.stage }}in the mailtemplate, printed in each recipient's language;optionis mail-only and refused in an inlinetitle/message; neverlabel()intemplateData, which is evaluated once per run, before fan-out. Read frommain:packages/formula/src/template-engine.ts(MAIL_ONLY_FORMATTERS = ['option'],optionFieldReference: bareobject.field),packages/plugins/plugin-email/src/email-service.ts(the label table is built per send in the recipient's locale),packages/services/service-automation/src/builtin/notify-node.ts(templateDatais a value-slot map resolved once per run; thetemplatelocale is resolved per recipient after fan-out),packages/formula/src/stdlib.ts(label()is the formula-field macro).#30731 —
skills/objectstack-automation/evals/flows-triggers-approvals.json. Eval 15: a stalled-opportunity e-mail whose subject shows the stage label in each recipient's language.must_contain:option:opportunity.stage,template,once per run;must_not_contain:source: 'label(and| label(the two wrong spellings a right answer never writes). Appended by splicing before the closing bracket, so no other case is reformatted.#30826 —
skills/objectstack-automation/SKILL.md, "Assignment rules". TheassignTo: { type: 'user', value: 'ID' }sentence now reads "names one owner, who holds the row only while an active member of its organization (else ownerless)". Read frompackages/objectql/src/assignment-rules.ts(organizationMemberStanding: asys_memberrow and no ban in force; the engine asks it of every user target at insert, declared rules included) andpackages/plugins/plugin-sharing/src/assignment-rule-hooks.ts(the save guard asks the same predicate).#30826 —
content/docs/automation/queues-and-assignment-rules.mdx, "2. Declare an assignment rule". Three paragraphs after "The rule writesowner_id…": the active-member rule for ausertarget; the organization's ownsys_assignment_rulerecords (Setup → Assignment Rules,manage_platform_settings; one rule with one entry;active), one namespace by name with the declared rules (mirroring the page'ssys_queueparagraph), evaluated first bysort_orderthennamewith the declaredassignmentRulesas the fallback (the activation ledger has no organization column), first match wins, a failed read of the organization's rules routes nothing; and what the save guard refuses. One checklist bullet. Pages checked for existing coverage before writing (maintainer rule, no duplicate sections):content/docs/automation/queues-and-assignment-rules.mdx(declared rules andsys_queueonly),content/docs/automation/index.mdx(one summary line, declared rules),content/docs/automation/approvals.mdx(thequeueapprover),content/docs/permissions/sharing-rules.mdxandcontent/docs/permissions/rls.mdx(queue recipients andcurrent_user.queues),content/docs/releases/v18/18-3.mdx(release-owned);content/docs/references/api/metadata.mdxandreferences/kernel/metadata-plugin.mdxlist theassignment_rulemetadata type only. No page mentionssys_assignment_rule; the generated references carry no page for the object.Changeset
.changeset/30731-automation-skill-notify-label-and-org-assignment-rules.md:'@objectstack/skills': patch, naming both cards.Ratchet
scripts/check-skills-token-ratchet.mjs: the SKILL.md row moves DOWN 6449 → 6448, re-locked at the measurement (headroom 0).Readings (
skills/**diff)origin/main677d542)skills/objectstack-automation/SKILL.mdlinesskills/objectstack-automation/SKILL.mdtokens (ceil((bytes − 20) / 4))skills/*/SKILL.md, linesskills/*/SKILL.md, tokensevals/flows-triggers-approvals.jsontokens (measured, not ratcheted)Deletions that pay for the two additions (same file)
## CRM Automation Blueprintsection (three lines + rule): thesrc/flows/*.flow.ts→src/flows/index.ts→defineStack({ flows })layout is carried byskills/objectstack-platform/references/bootstrap.md("Use barrel exports",import * as flows from './src/flows'intodefineStack({ flows: Object.values(flows) })), and the skill's frontmatter already names*.flow.tsas the trigger to load it.## Assignment rules — route a new record to a queue or a person; "scheduled automation" restated "Flows (… scheduled)" three words earlier.npm run validate." is carried by objectstack-formula's Verify section ("npm run validatein a scaffolded project"), which this skill names for CEL validation at its top.Each surviving sentence of the trimmed paragraphs was re-read against
main; nothing deleted has no other home. No line was re-wrapped to win room.Neighbour overlap
Seat 1's draft PR #30831 (#30805) edits
skills/objectstack-automation/SKILL.mdat lines 295 and 306–320 (the assignment-rule example's names and theapproversline) and eval cases 3, 7, 9, 11, 12 offlows-triggers-approvals.json. This PR's "Assignment rules" hunk changes the two lines directly above itsapproversline, so whichever lands second resolves one adjacent-line conflict there; thenotifyparagraph, the two deletions and eval 15 (appended at the file's end) are outside its hunks.origin/mainwas merged and the ratchet re-measured before each push.Tests
No package code changes. Local checks at this head:
node scripts/check-skills-token-ratchet.mjs→skills/objectstack-automation/SKILL.md is 6448 tokens (ceiling 6448; headroom 0);--self-testexit 0.json.load, 15 cases, ids 1–15).node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack, 69 lines) — see Verification.Acceptance notes
optionargument spelling to the bareobject.fieldformmainaccepts; the quoted, marked-path and one-sided forms are refused byoptionFieldReferenceand not taught.label()stays taught where it belongs (objectstack-formula, a formula field's display in the reader's locale); the automation skill now only says where it is wrong.## See alsopoints at the generatedassignment-ruleschema reference; no generated page exists for thesys_assignment_ruleobject, so the new prose names its columns inline.-c user.nameoverride); later commits use the container's defaultClaudeidentity. The squash on landing rewrites it either way.Verification
Derived gates at head 61f2a99 (base
677d542a): 87/87 families exit 0 — 69 derived first; the ratchet-row edit added 18 more; three (check:skill-examples,check:dual-build-cjs-loads,check:lean-entry-closure) first exited 3 on an unbuilt tree and exit 0 afterpnpm build --filter='./packages/**'(80/80 tasks, 7m58s under the verify lock).origin/main(five commits, none touching this PR's files) was then merged as 18600c3 and the skill-text families re-run there:check-skills-token-ratchet(6448 / 6448, headroom 0),check:skill-identifier-liveness,check:pm-skill-id-lint,check:doc-authoring,check:role-word, speccheck:skill-docs,check-empty-changeset,check:docs-single-h1— all exit 0. The per-command exit lists are/mnt/project-files/skills-seat-2/r2026-11-06/out/30731-gates-ran-61f2a99e.listand…-18600c34-merged.list, reconciled withdispatch-gates.mjs --repo objectstack-ai/objectstack --ran.Relay writes:
pr_create(this PR);post-stamped.mjsfor the os-dev-report on #30731. MCP GitHub calls: reads only (issue_read×6,pull_request_read×1 for #30831's file list); 0 MCP writes. The harness's assignee/reviewer step is skipped (no MCP writes; the seat sets the assignee at hand-over).Generated by Claude Code