Skip to content

spec(automation): the notify recipients describe names a written-out address as an author constant, and drops the bare "an email address" audience selector — the spec half of ruling B on #25647 #25696

Closed

Description

@objectstack-fleet

Filing gate ③, a follow-up owed by a ruling: the domain:spec half of ruling B on #25647 (6386629237, batch objectstack-ai/objectui#12 item 2, maintainer 「25635 25647 25675 同意」). The ruling says the spec lane files it. Filed by domain:spec seat 2 (seat post #18549) · sunhaolin · session session_01PC4NPXPgPmpDRG9DdDnyXT. ⛔ Not a claim. Grade and routing are triage's.

The ruling (verbatim)

「B = 只关「表达式算出来的地址」:notify 收件人若由表达式(CEL 信封)求值得到一个不属于任何用户的邮箱地址,节点失败并给出定位提示指向 { emailField };求值得到某个用户的地址仍解析为该用户。元数据里写死的地址是作者常量,照常发出。」 Workload: 「domain:server 1 个 PR(service-automation 的 resolveRecipients 或消息解析器),可并入 #25571 的文件;domain:spec 改描述文字,把「写死地址」写成作者常量,并从受众选择器列表里去掉笼统的「an email address」。」

Scope (for triage)

Dedupe

Parent: #25647 (ruled B). The PR that added { emailField } (#25645, 6021b5e837) left this text as it was. Semantic issue search "notify recipients describe email address author constant audience selector": 2 hits, #25610 (the { emailField } protocol half, closed) and #25444 (its parent ask, closed), neither of them this text change. New.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 24, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade — documentation · priority:p2 · domain:spec · area:workflow · pm:queue · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-24T17:54Z

    ⛔ Not a claim, ⛔ not a dispatch.


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 24, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 3
    Session: session_01PC4NPXPgPmpDRG9DdDnyXT
    Account: sunhaolin (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-25696-notify-recipients-describe
    Worktree: objectstack-issue-25696
    Domain: domain:spec
    Seat: domain:spec#2 (seat post #18549)
    File surface: text only, in packages/spec/src/automation/io-node-config.zod.ts: the recipients docblock that lists the audience selectors (about :355), the refusal-rule sentence (about :324), and the two .describe() strings (about :391, :632).


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 24, 2026

    @objectstack-fleet
    ContributorAuthor

    Dispatched · round 3 · domain:spec seat 2 · 2026-10-24T22:34Z


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 25, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 25696,
      "status": "done",
      "branch": "claude/issue-25696-notify-recipients-describe",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/25739",
      "session": "session_01PC4NPXPgPmpDRG9DdDnyXT — subagent of the PM seat session (the claim 6390309606 names it); commits carry Claude-Session: https://claude.ai/code/session_01PC4NPXPgPmpDRG9DdDnyXT",
      "premise_still_valid": true,
      "summary": "Text only, in packages/spec/src/automation/io-node-config.zod.ts, per ruling B 6386629237 on #25647 and triage 6387591836. The recipients docblock no longer lists \"an email address\" among the audience selectors (now \"such as team:ID\"). A string address the author writes out is named an author constant, sent as written: to the user who holds it, or else, on the email channel, to the address itself. An address a CEL envelope evaluates to resolves to the user who holds it. Failing the node on one that no user holds, pointing to { emailField }, is stated as PLANNED and not made yet, because #25647 and #25571 are both still open (now pm:dispatched) and absent from origin/main. Both the field .describe() and the union .meta() description say this. NOTIFY_RECIPIENTS_RULE (the refusal lead sentence) now lists the written-out address beside a user id and a selector. The email-field section note no longer calls { emailField } the one address form. Also: content/docs/references/automation/io-node-config.mdx regenerated with gen:docs (the only artifact check:generated proved stale), and changeset .changeset/25696-notify-recipients-describe.md (@objectstack/spec minor; Clause-②: no; Metadata-protocol: semantic; Ruling-ref: 6386629237). No key, shape, default or enum changes. origin/main 4cc17db3c0 is merged in (merge commit 6cfe103516, no conflicts, none of my three files touched by main). Every reading below was retaken after that merge. The pre-merge cli run cut off by the session limit is not counted. Trade-offs I decided myself are recorded HERE, not in open_questions. The role file defines open_questions as decision-shaped, and it wins over the dispatch on conflict. A non-empty open_questions on a card without needs-user-decision trips check-half-states H52 as an unreachable maintainer question. Trade-off (1): I extended NOTIFY_RECIPIENTS_RULE so that a refused author sees every accepted string spelling. Only its pinned opening is unchanged. Trade-off (2): the delivery claim is limited to the email channel, because inbox handling of an address no user holds was not measured. Trade-off (3): content/docs/automation/flows.mdx:340 is left as it is. It never called a bare address a selector, so it is not made false, and it is outside the claim file surface. Follow-up the runtime half owes: when #25647 lands, its PR must flip the \"planned and not made yet\" sentences to \"made\". The docblock records this. Housekeeping slip: a background launch with a subshell-scoped variable wrote a stray 6-byte pid file at /full-build.pid. The harness safety check refused its removal, so it is still there; please delete it by hand. It is harmless.",
      "tests": "All at head 6cfe103516 (merged tree), each through scripts/pm/os-verify-lock.sh, reading its VERDICT line. Full build: turbo run build --filter=!@objectstack/docs --concurrency=2, VERDICT command-exit 0, 76 tasks. pnpm --filter @objectstack/spec test: Test Files 721 passed (721), Tests 21833 passed | 1 todo (21834). pnpm --filter @objectstack/spec test:repo: Test Files 79 passed (79), Tests 1269 passed (1269). The two spec suites ran as one locked call: VERDICT command-exit 0. pnpm --filter @objectstack/spec typecheck: VERDICT 0 (check:test-typecheck: OK). Consumers that read NotifyConfigSchema / FlowSchema, full suites (none has a test:repo script): @objectstack/lint: 161 passed (161) files, 7285 passed (7285) tests, VERDICT 0. @objectstack/service-automation: 201 passed (201) files, 2636 passed (2636) tests, VERDICT 0. @objectstack/metadata-protocol: 263 passed | 3 skipped (266) files, 21485 passed | 19 skipped (21504) tests, VERDICT 0. @objectstack/cli, unit and integration (pnpm --filter @objectstack/cli test): Test Files 501 passed | 1 skipped (502), Tests 6297 passed | 9 skipped (6306), VERDICT 0, held 41m25s. Pre-merge readings at c41e582098 were green as well: spec test 21821 passed; test:repo 1269 passed; lint 7280; service-automation 2636; metadata-protocol 21485. No ablation: no tested behaviour changes, and no refusal or fail-closed branch is added. The text is not pinned either (the role file does not pin wording); the existing pins hold: the rule opening, recipients describe contains \"adds each of its recipients\" and \"template token is refused\".",
      "gates": "LOCAL at 6cfe103516: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derives 107 commands (change set: 3 paths vs merge base 4cc17db3c of origin/main). Each command was run with its exit code captured to the ran list before any pipe: 107 of 107 exit 0, with the full build present. The pre-merge pass at c41e582098 was also 107 of 107 exit 0, after 6 first exited 3 for unbuilt packages and were re-run post-build. --ran prints: \"✓ dispatch-gates --ran: 107 derived famil(ies) accounted for — 107 run, 0 NOT-MEASURED (a DERIVED zero — all 107 recorded an exit code and none of them is 3).\" Includes check:generated 0, check:docs 0, check:authorable-surface 0, check:api-surface 0, check:liveness 0 (on the 4cc17db3c0 base), check:nul-bytes 0. node scripts/docs-audit/affected-docs.mjs --json origin/main: \"0 docs name something this change touched\". node scripts/pm/check-governed-merges.mjs --pr 25739: NOT governed, 71 changed lines. CI on PR #25739 head 6cfe103516, required five: Lint & Repo Gates success; TypeScript Type Check success; Build Core success; Governed Surface Queue Guard success; Test Core 2/6, 3/6, 4/6, 5/6 and 6/6 success, 1/6 FAILURE. Test Core 1/6: step \"Run this shard's tests\", annotation \"command (packages/spec) pnpm run test exited (1)\", no file-anchored assertion. The job log is NOT RETRIEVED: the proxy refuses the redirect host productionresultssa16.blob.core.windows.net, so the failing assertion is NOT MEASURED. The CI merge ref (6cfe103516 merged into e2b40a264b) carries a packages/spec tree byte-identical to the one that passed spec test 721/721 locally (git diff --stat 6cfe103516 against the merge ref, packages/spec: empty), and origin/main has no packages/spec commit since 4cc17db3c0. So it reads as an environment flake, not this diff. Recommend one rerun of the failed job (relay run_rerun_failed); I did not spend a write on it. Advisory: Spec property liveness FAILURE, main-caused (see out_of_scope_findings). Other advisory checks: Build Docs, Check Changeset, Dogfood Regression Gate, Flag docs affected and every Lint and Type Check lane all success.",
      "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm (Clause-②: no)",
      "mcp_calls": "0 — no MCP GitHub tool called (reads went through gh api REST reads)",
      "api_writes": "2 — POST /repos/objectstack-ai/objectstack/dispatches (fleet-write relay, one pr_create action, created #25739 as draft with assignee sunhaolin; read-back identical, 9198 bytes) and POST /repos/objectstack-ai/objectstack/issues/25696/comments (this os-dev-report, via scripts/pm/post-stamped.mjs). Not REST: 4 git pushes (empty probe branch, two commits, the merge). Zero labels written.",
      "open_questions": [],
      "out_of_scope_findings": [
        "class: a · reach: CI gate \"Spec property liveness\" red on PRs and main merge groups whose tree includes commit 0189524a41: this PR's run 40160567276, and the merge-group builds of e44a1ffc4d, e2b40a264b, 5cf1b9d2e8, 97277f18f9, f871670fef and c61f75d10f, all conclusion failure in the spec-liveness-check.yml run list · evidence: `pnpm --filter @objectstack/spec check:liveness` exits 1 on origin/main 5cf1b9d2e8 in a clean compare worktree: \"✗ 1 'live' / 'planned' / 'experimental' / 'live-elsewhere' citation(s) name a file that never names the property: translation/flows.screens → packages/services/service-automation/src/engine.ts\". Control leg: the same gate exits 0 at 6cfe103516 = 4cc17db3c0 + this diff. The only commit in 4cc17db3c0..5cf1b9d2e8 touching engine.ts is 0189524a41 (refactor(service-automation): move AutomationEngine.resumeInternal body into run-resume.ts, #25734), so the citation needs repointing (likely to run-resume.ts). Main-red convention, the lane of #25734 · dedupe words: liveness translation flows.screens engine.ts, check:liveness main red, run-resume.ts resumeInternal citation",
        "carrier: #25647 (runtime half) · noted, not filed: objectui 7981384 packages/app-shell/src/views/metadata-admin/inspectors/FlowRecipientsField.tsx:12 \"Record field\" row stores { dialect: 'cel', source: 'record.FIELD' } for any trigger-record field; over an email-typed field that is exactly the computed address ruling B will refuse once the runtime half lands, so the picker should route email-typed fields to { emailField } in that landing. Its \"Email address\" row (:15) writes an author constant, unaffected.",
        "carrier: none (承接者:无) · noted, not filed, Acceptance notes only: examples/app-showcase/src/automation/flows/index.ts:1435 notifies exec@example.com (no user holds it) with no channels, i.e. the default inbox; what the inbox channel does with an address no user holds was not measured."
      ]
    }

    Generated by Claude Code

  5. objectstack-fleet commented on Oct 25, 2026

    @objectstack-fleet
    ContributorAuthor

    Cross-lane note · domain:server seat 1 (seat post objectstack-ai/objectui#6367) · session_01R1q2xdtYgU6FKrZ7LgjPCC · 2026-10-25T04:44Z · ⛔ Not a claim.

    The runtime half this card waits on has landed: PR #25721 (d1e329e96d, 2026-10-25T04:41:00Z) closed #25571 and #25647. From now on, the recipients describe in packages/spec/src/automation/io-node-config.zod.ts (and its generated row in content/docs/references/automation/io-node-config.mdx) is false where it says "Delivery to an email-field recipient is not live yet: until the messaging service resolves the form, a run that reaches the node fails there." The { emailField } form now mails. The contract review on #25721 (6392736321, flag F4) asks for this card to land next, not a release later.

    Facts the describe can now state, all on main:

    • A computed recipient that reads as an address (bare, or after one user:) resolves to the user who holds it, or fails the node pointing to { emailField }. This applies only in a node whose channels include email; the channel scope is with the maintainer as a confirmation. A written-out address is the author's constant and is sent as written.
    • { emailField } mails one plain-ASCII address read from the stored trigger record, at most 5 sends per address per hour. The limit is best-effort when the cache counter faults.

    Landing record: #25571 (comment)


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 25, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 25696,
      "status": "done",
      "branch": "claude/issue-25696-notify-recipients-describe",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/25739",
      "session": "session_01PC4NPXPgPmpDRG9DdDnyXT — subagent of the PM seat session (the claim 6390309606 names it); commits carry Claude-Session: https://claude.ai/code/session_01PC4NPXPgPmpDRG9DdDnyXT",
      "premise_still_valid": true,
      "summary": "Patch round 1 (addendum to report 6393558914). The runtime half landed in #25721 (d1e329e96d), so the text now states what is made. Merged origin/main d1e329e96d as merge commit f6c07d3953, with no rebase and no conflicts. #25742 had not landed by head time; origin/main has since moved only to f9a1e93f43 (#25690, unrelated), which is not merged. Changes in packages/spec/src/automation/io-node-config.zod.ts, commit 1a41859ca9: (1) The docblock paragraph now says: made by #25721 / d1e329e96d (screenComputedAddresses). In a node whose channels include email, a computed recipient that reads as an address, bare or as user:ADDRESS, must be a user's. A held address resolves to that user. One no user holds, or one that cannot be looked up, fails the node pointing to { emailField }. A node without email mails nobody, and its computed recipients reach the messaging resolver unscreened. The channel scope is stated as current behaviour that the maintainer is confirming, not as final. (2) A docblock paragraph on email-field delivery: the address is read from the STORED trigger row, must be one plain ASCII mailbox, and one address receives at most 5 sends per hour, best-effort when the cache counter faults. (3) The field .describe(): the \"Delivery to an email-field recipient is not live yet ... fails there\" sentence is replaced with the stored-record, one-ASCII-mailbox and 5-per-hour behaviour, and the computed-address sentences are flipped from planned to made, with the email-channel scope. (4) The union .meta() description, flipped the same way. (5) The email-field section note now cites d1e329e96d delivery. The author-constant sentences and NOTIFY_RECIPIENTS_RULE are unchanged. The changeset text was rewritten to match. content/docs/references/automation/io-node-config.mdx was regenerated with gen:docs (commit 2e4fad24c5). Head is 2e4fad24c5, pushed. Step 3, re-checked: content/docs/automation/flows.mdx now carries #25721's email-field and computed-address paragraphs (from :359). They match the runtime and this text, so I changed nothing; :340 is still not false. No other hand-written page under content/docs or skills states this behaviour (git grep emailField / email-field recipient). CORRECTION of my earlier report: Test Core (1/6) is not an environment flake. Locally, spec test now fails 23 tests, all in scripts/liveness/check-liveness.test.ts, which reads service-automation's engine.ts. That breakage is main-caused by #25734 (0189524a41), and the fix is #25742. Not re-run, not ported. PR BODY IS NOW STALE: it still says the refusal is planned, and its body was written once at pr_create. A replacement body is ready for the seat to write, at /tmp/claude-0/-home-user/d69aa6c5-ba90-5942-ba67-096819effb0b/scratchpad/issue-25696/pr-body-round1.md (8.9 KB). It has the same first line and declaration lines, the What section updated, a new \"The refusal is made\" section, this round's Verification, and updated Acceptance notes. It is linted: no closing keyword besides Fixes #25696, no angle brackets, no control bytes. Cleanup: worktree /home/user/objectstack-issue-25696 is kept for a possible next round (re-created from the pushed branch at 6cfe103516 this round). The stray /full-build.pid at the filesystem root from round 0 is still there; the safety check refused its removal.",
      "tests": "All at head 2e4fad24c5 (origin/main d1e329e96d merged), through os-verify-lock, reading VERDICT lines. pnpm install --frozen-lockfile exit 0. Full build turbo run build --filter=!@objectstack/docs --concurrency=2: VERDICT command-exit 0. pnpm --filter @objectstack/spec test: Test Files 1 failed | 720 passed (721), Tests 23 failed | 21810 passed | 1 todo (21834), VERDICT command-exit 1. All 23 failures are in scripts/liveness/check-liveness.test.ts (main-caused, #25734 to #25742). Control leg: 721/721 green at 6cfe103516, before 0189524a41 was merged in. pnpm --filter @objectstack/spec test:repo: Test Files 79 passed (79), Tests 1269 passed (1269), VERDICT 0. pnpm --filter @objectstack/spec typecheck: VERDICT 0. @objectstack/lint: 161 passed (161) files, 7285 passed (7285) tests, VERDICT 0. @objectstack/service-automation: 202 passed (202) files, 2659 passed (2659) tests, VERDICT 0. @objectstack/metadata-protocol: 263 passed | 3 skipped (266) files, 21485 passed | 19 skipped (21504) tests, VERDICT 0. cli was not re-run this round (not asked; text-only delta). It was 501 passed | 1 skipped at 6cfe103516. No ablation: no tested behaviour changes.",
      "gates": "LOCAL at 2e4fad24c5: dispatch-gates --commands --repo objectstack-ai/objectstack derives 107 (change set: 3 paths vs merge base d1e329e96). Result: 105 exit 0, and 2 exit 1: pnpm --filter @objectstack/spec run check:liveness, and pnpm --filter @objectstack/spec run check:generated (its only red lane is check:liveness; check:docs is green after gen:docs). Both name only \"translation/flows.screens → packages/services/service-automation/src/engine.ts\", the main-caused row #25742 fixes. --ran prints: \"✓ dispatch-gates --ran: 107 derived famil(ies) accounted for — 107 run, 0 NOT-MEASURED (a DERIVED zero — all 107 recorded an exit code and none of them is 3).\" affected-docs --json origin/main: \"0 docs name something this change touched\". Control-byte scan: no hits. CI on 2e4fad24c5: Lint & Repo Gates success; TypeScript Type Check success; Build Core success; Governed Surface Queue Guard success; Check Changeset success; Build Docs success; Test Core 2/6, 3/6, 4/6 and 6/6 success, 5/6 in_progress, 1/6 failure (check-liveness.test.ts, main-caused); Spec property liveness failure (main-caused). Both reds clear when #25742 lands and main is merged.",
      "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm (Clause-②: no)",
      "mcp_calls": "0 — no MCP GitHub tool called this round or before",
      "api_writes": "1 this round — POST /repos/objectstack-ai/objectstack/issues/25696/comments (this addendum, via scripts/pm/post-stamped.mjs and the relay). 3 in total with round 0 (relay pr_create, report 6393558914, this addendum). Not REST: 3 git pushes this round (merge f6c07d3953, 1a41859ca9, 2e4fad24c5). No PR body PATCH: the seat writes the stale body (see summary).",
      "open_questions": [],
      "out_of_scope_findings": [
        "class: a · reach: exception: release-text · evidence: .changeset/25610-notify-email-field-recipient.md:25 (pending, on main) says email-field delivery \"lands separately; until it does, a run that reaches such a node fails at the node\". #25721 (d1e329e96d) made that false, and it would ship as @objectstack/spec CHANGELOG text beside .changeset/25571-notify-email-field-delivery.md, which says the opposite. It needs a docs-only edit of that changeset before the release; outside this card's file surface · dedupe words: 25610 changeset email-field delivery lands separately, notify email-field changeset stale",
        "class: a · reach: CI on main (already routed: #25742, dispatched by the seat) · evidence: check:liveness and scripts/liveness/check-liveness.test.ts red since 0189524a41 (#25734): translation/flows.screens cites service-automation engine.ts. Listed only to correct my round-0 flake reading; no new filing · dedupe words: liveness flows.screens engine.ts",
        "carrier: the runtime lane (#25721 landed; picker follow-up) · noted, not filed: objectui 7981384 FlowRecipientsField.tsx:12 \"Record field\" row stores a record.FIELD envelope; over an email-typed field on an email node, that is now refused unless a user holds the address, so routing such fields to { emailField } belongs to that lane."
      ]
    }

    Generated by Claude Code

  7. objectstack-fleet commented on Oct 25, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim addendum (amends the file surface of 6390309606, round 3) · domain:spec seat 2 · 2026-10-25T05:36Z

    Patch round 1 (addendum on this card, head 2e4fad24c5) states the computed-address refusal as made, since #25721 (d1e329e96d) landed its runtime half. It stays within the claimed surface: io-node-config.zod.ts text, the regenerated content/docs/references/automation/io-node-config.mdx, and this PR's own changeset.

    Patch round 2 widens the surface by one file: .changeset/25610-notify-email-field-recipient.md, its last prose paragraph only.

    • What is wrong with it today. That paragraph says email-field delivery "lands separately; until it does, a run that reaches such a node fails at the node". feat(service-automation)!: notify mails an email-field recipient, limited per address, and refuses a computed address no user holds #25721 made that false. Both changesets are pending on main, so at the next release the false sentence would ship as @objectstack/spec CHANGELOG text beside .changeset/25571-notify-email-field-delivery.md, which says the opposite.
    • Why it rides this PR. Same feature, same package, same release, and this PR already carries the made wording.
    • What stays unchanged. The changeset's frontmatter levels and its Clause-② / Metadata-protocol lines.
    • Governance. Not a governed path. The dev's round-1 finding is the source (class a, release text).

    Generated by Claude Code

  8. objectstack-fleet commented on Oct 25, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim addendum (withdraws the widening in 6393983728) · domain:spec seat 2 · 2026-10-25T05:41Z

    The one-file widening is withdrawn. Check Changeset refused the edit to .changeset/25610-notify-email-field-recipient.md on aed84ec582. Correcting someone else's pending release note is a release decision that the gate (#17712, ruling D) holds red until a person confirms it. Riding this PR, it would have held #25739's landing on a decision that is not this PR's.


    Generated by Claude Code

  9. objectstack-fleet commented on Oct 25, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 25696,
      "round": "patch round 2 (addendum to 6393965971): edit made, then reverted on the seat correction",
      "status": "done",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/25739",
      "head": "29733bf86f",
      "head_tree_equals": "2e4fad24c5 (tree 1822e5fdc05a), so every round-1 suite reading stands for this head",
      "commits_this_round": [
        "aed84ec582: rewrote the last paragraph of .changeset/25610-notify-email-field-recipient.md",
        "29733bf86f: restored that file to its merge-base text. git diff d1e329e96d on the file is empty; blob 2e8f4685d2a8 at both the merge base and HEAD; git status clean"
      ],
      "reverted_paragraph_text": "This change is the protocol half. Delivery — resolving the field to an address, the outbound mail configuration, the per-address rate limit and the messaging-log entry — is the runtime half, and it ships in this same release in the `notify` node of `@objectstack/service-automation`.",
      "why_reverted": "At aed84ec582, node scripts/check-empty-changeset.mjs --base origin/main exited 1 locally: \".changeset/25610-notify-email-field-recipient.md exists on the merge base and was not added by this PR\". This is the foreign-correction refusal, which the seat correction names. Merge base d1e329e96d; origin/main not merged this round.",
      "gates": [
        "node scripts/check-empty-changeset.mjs --base d1e329e96d :: exit 0",
        "node scripts/check-adr-0087-registration.mjs --base origin/main :: exit 0",
        "node scripts/check-adr-0087-registration.mjs --self-test :: exit 0",
        "node scripts/check-changeset-no-major.mjs --base origin/main :: exit 0",
        "node scripts/check-changeset-no-major.mjs --self-test :: exit 0",
        "node scripts/check-closing-keyword-parity.mjs :: exit 0",
        "node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0",
        "node scripts/check-comment-mask-corpus.mjs :: exit 0",
        "node scripts/check-empty-changeset.mjs --base origin/main :: exit 0",
        "node scripts/check-empty-changeset.mjs --self-test :: exit 0",
        "node scripts/pm/release-rehearsal-clone.mjs --self-test :: exit 0",
        "node scripts/release-pending-publish.mjs --self-test :: exit 0",
        "pnpm check:changeset-gate-self-tests :: exit 0",
        "pnpm check:closed-ceremony-text :: exit 0",
        "pnpm check:driver-memory-census :: exit 0",
        "pnpm check:gitlink-declared :: exit 0",
        "pnpm check:nul-bytes :: exit 0",
        "pnpm check:objectui-changeset :: exit 0",
        "pnpm check:pm-changeset-deadline-census :: exit 0",
        "pnpm check:published-files :: exit 0",
        "pnpm check:refd-timer-probe :: exit 0",
        "pnpm check:watch-hint-literal :: exit 0",
        "Check Changeset count step, local equivalent (git diff --name-only --diff-filter=A d1e329e96d HEAD -- .changeset/*.md): exit 0, one added file, .changeset/25696-notify-recipients-describe.md"
      ],
      "gates_note": "Recorded at 29733bf86f, each exit code captured before any pipe. The list is the 21 commands dispatch-gates --commands derives for .changeset/25610-notify-email-field-recipient.md, plus an explicit --base d1e329e96d run of check-empty-changeset. Declared narrowing per the seat order: no full build and no full suites, because the net delta since 2e4fad24c5 is zero (same tree). The PR change set vs the merge base is back to 3 paths.",
      "pr_body_file": "/tmp/claude-0/-home-user/d69aa6c5-ba90-5942-ba67-096819effb0b/scratchpad/issue-25696/pr-body-round1.md, updated in place, 9661 bytes. Verification head is now 29733bf86f, with a same-tree note. What-this-changes carries no 25610 bullet. The Acceptance-notes bullet says the pending 25610 changeset paragraph has been false since #25721, that the release-note gate (#17712) holds a correction of it for a person, and that the seat filed it for the maintainer. Lint: the only closing keyword is Fixes #25696; no angle brackets; no control bytes. Not written to GitHub.",
      "mcp_calls": "0",
      "api_writes": "1 this round — POST /repos/objectstack-ai/objectstack/issues/25696/comments (this addendum, via scripts/pm/post-stamped.mjs and the relay). Not REST: 2 git pushes (aed84ec582, 29733bf86f), plain commits with no rebase, amend or force.",
      "open_questions": []
    }

    Generated by Claude Code

  10. objectstack-fleet commented on Oct 25, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 25696,
      "round": "patch round 3 (addendum to 6394072990): the email-channel scope is confirmed, text only",
      "status": "done",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/25739",
      "head": "83ce3e8bad",
      "ruling_read": "Ruling record 6393736930 on #25647: the maintainer chose 「A:只查含 email 通道的节点」. I read the comment before writing.",
      "new_sentences": {
        "packages/spec/src/automation/io-node-config.zod.ts (recipients docblock)": "That channel scope is the confirmed reading of the ruling (ruling record 6393736930 on #25647: the maintainer chose to screen only nodes that include the `email` channel).",
        ".changeset/25696-notify-recipients-describe.md": "The screen is scoped to nodes that include the `email` channel (confirmed by the maintainer)."
      },
      "replaced_sentences": [
        "docblock: \"That channel scope is the runtime's current reading of the ruling and is with the maintainer for confirmation, so the describes below state it as the current behaviour, not as final.\"",
        "changeset: \"This is the current behaviour of the notify node; the channel scope is with the maintainer for confirmation.\""
      ],
      "describe_strings": "Unchanged. Neither .describe() nor .meta() hedged the scope, so gen:docs was not needed, and check:docs exits 0 at this head. git grep -n -i \"confirmation\\|not as final\" over io-node-config.zod.ts and .changeset/25696-* exits 1 (no hits).",
      "gates": {
        "derived": "dispatch-gates --commands --repo objectstack-ai/objectstack for the two changed paths derives 83 commands. 82 exit 0, and 1 exits 1: pnpm --filter @objectstack/spec run check:liveness :: exit 1 (the main-caused translation/flows.screens row). --ran prints: \"✓ dispatch-gates --ran: 83 derived famil(ies) accounted for — 83 run, 0 NOT-MEASURED (a DERIVED zero — all 83 recorded an exit code and none of them is 3).\"",
        "changeset_family": "check-empty-changeset --base origin/main 0 and --self-test 0; check-adr-0087-registration --base origin/main 0 and --self-test 0; check-changeset-no-major --base origin/main 0 and --self-test 0; check:changeset-gate-self-tests 0; check:nul-bytes 0.",
        "check_generated": "pnpm --filter @objectstack/spec check:generated exits 1. Its only red lane is check:liveness (\"✗ 1 of 14 artifact(s) stale\"); check:docs is green.",
        "spec_build": "pnpm --filter @objectstack/spec build: VERDICT command-exit 0. This is the package's own build, run before the dist-reading gates; no full build.",
        "spec_typecheck": "VERDICT command-exit 0.",
        "spec_test": "Test Files 1 failed | 720 passed (721), Tests 23 failed | 21810 passed | 1 todo (21834), VERDICT command-exit 1. All 23 failures are in scripts/liveness/check-liveness.test.ts, the main-caused file, as expected.",
        "spec_test_repo": "Test Files 79 passed (79), Tests 1269 passed (1269), VERDICT command-exit 0."
      },
      "pr_body_file": "/tmp/claude-0/-home-user/d69aa6c5-ba90-5942-ba67-096819effb0b/scratchpad/issue-25696/pr-body-round1.md, updated in place, 10090 bytes. The scope bullet now reads \"That channel scope is confirmed (ruling record 6393736930 on #25647).\" Verification head is now 83ce3e8bad, with this round's readings. Lint: the only closing keyword is Fixes #25696; no angle brackets; no control bytes. Not written to GitHub.",
      "untouched": "origin/main was not merged, and .changeset/25610-* was not touched.",
      "mcp_calls": "0",
      "api_writes": "1 this round — POST /repos/objectstack-ai/objectstack/issues/25696/comments (this addendum, via scripts/pm/post-stamped.mjs and the relay). Not REST: 1 git push (83ce3e8bad), a plain commit.",
      "open_questions": []
    }

    Generated by Claude Code

  11. objectstack-fleet commented on Oct 25, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:spec seat 2 (seat post #18549) · sunhaolin · session session_01PC4NPXPgPmpDRG9DdDnyXT · 2026-10-25T15:09Z

    reading value
    PR #25739 MERGED through the queue at 2026-10-25T15:08:46Z; merge commit 52f3f518e1. ACCEPT 6394280653; CONTRACT_REVIEW_TIER PASS 6395784809 on 83ce3e8bad, confirmed by PASS 6398822689 on the landing head 0433b8133f (main merged in, the PR's own three files byte-identical). ci-failure read GREEN, 48/48, and check-governed-merges read NOT governed
    queue branch gh-readonly-queue/main/pr-25739-* gone (REST matching-refs: 0 refs)
    origin/main carries 52f3f518e1; packages/spec/src/automation/io-node-config.zod.ts names "author constant" (5 hits), cites ruling record 6393736930, and no longer says "not live yet"

    State: the card closed completed on the merge (Fixes #25696). pm:dispatched is removed in this stroke. The dev was a subagent of this seat's session, so there is no cloud session to archive. Its worktree is removed.


    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

Labels

area:workflowApprovals and automation — the work that runs without a person driving itdocumentationImprovements or additions to documentationdomain:specpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions