Skip to content

fix(plugin-email)!: retire renderTemplate, the render export that takes an email template body with no save moment - #26399

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/project-thread-s91v0o
Oct 27, 2026
Merged

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/project-thread-s91v0o

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Requested by Leehom · project thread
Fixes #25190

Clause-②: no (narrowing)
Metadata-protocol: none
Skills-docs: none — no skills/** file names the retired package export, and content/docs/** names only services.email's renderTemplate method (automation/email-templates.mdx lines 14, 224, 261), which stays; nothing teaches the removed export

维护者速读

  • 改了什么:@objectstack/plugin-email 的包入口不再导出 renderTemplate 函数;函数本身留在包内,邮件服务照常用它渲染已存储的邮件模板。
  • 为什么改:这个导出直接接收一段模板正文并当场渲染,没有保存环节,邮件 HTML 洞位规则(在编写/发布时判定)看不到它;退役后不再有规则看不见的渲染入口。这是本卡的第二个也是最后一个 PR(renderNotification 已由 fix(service-messaging)!: retire renderNotification, the render export that takes a notification template body with no save moment #25285 退役)。
  • 风险与回滚:本仓与 hotcrm 从包入口导入它的数量为 0;外部若有直接导入者会在自己的 import 处得到编译错误,changeset 写明改用 services.email 的 renderTemplate / sendTemplate。回滚 = revert 本 PR。
  • 先看:packages/plugins/plugin-email/src/index.ts(删除的那一行导出);.changeset/25190-retire-render-template-export.md(BREAKING 说明与 FROM → TO);packages/plugins/plugin-email/src/render-export-retired.pin.test.ts。
  • 两分钟验证:node scripts/check-adr-0087-registration.mjs --base origin/main,预期 exit 0 且打印 verified: @objectstack/plugin-email#renderTemplate。
  • 需要你做的:无,席位落地。

What changes

Tests

  • New src/render-export-retired.pin.test.ts (3 cases): the entry has no renderTemplate; control: requireVars, htmlToText, createRegistryEmailTemplateLoader, EmailServicePlugin are still exported; a stored template renders by name through EmailService.renderTemplate and sendTemplate, html hole encoded, subject verbatim.
  • Reverse check (one-off, no permanent file): with the base index.ts restored, the retired-name case went red (1 failed, 2 passed); restored with git checkout HEAD, HEAD blob hash matched.

Acceptance notes

  • Restart line of the hold (6351169534) measured on this real head, not from the record: check-adr-0087-registration --base origin/main exit 0, verified: @objectstack/plugin-email#renderTemplate (export, packages/plugins/plugin-email/src/template-engine.ts).
  • Readers swept: no import of renderTemplate from @objectstack/plugin-email anywhere in this tree (tests, ui/, examples, docs, docs/qa/**, scripts/** included) or in objectstack-ai/hotcrm. content/docs/automation/email-templates.mdx names renderTemplate({ template, data, locale }), which is the service method, so it stays as written. No skills/** reader. The spec api-surface snapshots do not cover plugin-email.
  • npm dependants: NOT MEASURED. The registry has no dependants index; its text search ignores a dependencies: qualifier and returns unrelated packages.
  • Open PRs touching packages/plugins/plugin-email/**: none, read at start (20 open) and again before opening this PR (31 open).

Verification

All readings on head 0570b5e6, branched from origin/main 6390fe52.

ADR-0087 restart line: exit 0

node scripts/check-adr-0087-registration.mjs --base origin/main exit 0: .changeset/25190-retire-render-template-export.md [BREAKING+bang+clause-②-narrowing] not-required (runtime-export-retired) -- verified: @objectstack/plugin-email#renderTemplate (export, packages/plugins/plugin-email/src/template-engine.ts).

Package suite, typecheck, lint: all exit 0
  • Under os-verify-lock, pnpm --filter @objectstack/plugin-email build && … test && … typecheck: VERDICT command-exit 0. Test Files 39 passed (39), Tests 702 passed (702). The typecheck ran tsc --noEmit and check:test-typecheck (the test layer included).
  • pnpm exec eslint --no-inline-config packages/plugins/plugin-email exit 0.
  • node scripts/check-platform-checklist.mjs --changed-from origin/main exit 0: 0 anchored files, nothing judged.
Derived gates: 65 of 65 exit 0
  • dispatch-gates --commands --repo objectstack-ai/objectstack derived 65 families. All 65 were run, with each exit code captured before any pipe, and all 65 exit 0.
  • Two needed a prerequisite before they returned a verdict. check-plugin-teardown-shape --self-test exited 3 (shallow clone) until its pinned fixture commit 621a4876 was fetched, then exit 0 (48 cases). check:dual-build-cjs-loads exited 3 (no dist) until a full build ran, then exit 0 (112 entry points across 69 packages).
  • --ran: 65 derived, 65 run, 0 NOT-MEASURED, exit 0.
Full dogfood battery (bang title): 2 files red, both red on main and not touched by this diff

🤖 Generated with Claude Code

https://claude.ai/code/session_014LDnV6FyUqxjaBRSi5Kv1L

The function took a template body inline and rendered it with no save
moment, out of the hole-placement rule's sight. services.email keeps
rendering stored email_template items through it.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014LDnV6FyUqxjaBRSi5Kv1L
@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tests tooling labels Oct 27, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️ 1 changed file(s) yielded no anchor (packages/plugins/plugin-email/src/index.ts), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)).

What this run could not see
  • 1 changed file(s) yielded no anchor (packages/plugins/plugin-email/src/index.ts) — pages documenting those are invisible to this run
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.
  • a key NAME is not a key, so the hand re-read the line above prescribes can land on the wrong schema. The same spelling is authorable on one governed type and a [REMOVED] tombstone on another for each of active, aria, joins, objects, template, tools and version (censused on [finding] tools is a key on BOTH AgentSchema (tombstoned, dead) and SkillSchema (live, cloud-attested), so a name-based search attributes skill examples to the agent key — it produced a false stop-the-line alarm on PR #19059 #19093 over the liveness ledger's governed types, top-level keys); nothing in a search result distinguishes the two, so a grep hit on a LIVE example reads as evidence about the DEAD key. Measured on fix(spec): the agent.tools liveness row says dead — it claimed live on a key the schema tombstoned #19059: content/docs/ai/agents.mdx was reported as contradicting the agent.tools tombstone over its tools: example at :161, which is inside the defineSkill({ block opened at :155 — the page was already correct. Settle ownership by PARSING the value against both schemas, never by the name: that literal PASSES SkillSchema, and as an AgentSchema it FAILS at tools with the tombstone prescription. ⛔ These names are not the whole class — a key retired through a .strict() guidance map leaves no tombstone in the walked shape and none of them here (tool.category, live as AIToolDefinition.category).

Coarse fallback — 6 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 13136f73b727290d9549bf9dd574fc0587715388 → packageMentionDocs.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 0570b5e6e58b4accce82bd6cf6d1c948a78a7e06
Local-runs: none
Scope: packages/plugins/plugin-email/src/index.ts, packages/plugins/plugin-email/src/render-export-retired.pin.test.ts + packages/plugins/plugin-email/src/template-engine.ts, packages/plugins/plugin-email/src/email-service.ts, packages/plugins/plugin-email/package.json (exports, files), packages/spec/src/contracts/email-service.ts (IEmailService), packages/services/service-messaging/src/index.ts (interpolate), tsup.config.ts (entry)

Face: narrowing (Clause-②: no (narrowing) line-initial on the PR body and on .changeset/25190-retire-render-template-export.md; no schema and no governed path in the diff). Inputs read: card #25190 body and all 11 comments (rulings 6335348115 on #25082, 6349343463, 6349391984, 6351169534, the spec-lane notes 6350996010 / 6356337552, the ops reading 6392298822, the claim 6430890446 and the dev report 6431921813); PR #26399 body, file list and the net diff 6390fe52..0570b5e6 against main (one commit, three files: +18 changeset, +6/−1 index.ts, +81 pin test); the check-runs on the head. Nothing was built, run or re-run; the record template was printed with record-recognisers --template --face narrowing as the brief asked.

① Derived judgments

Every accept-set / public-surface change the diff implies, named right or wrong:

  1. The entry change is exactly one runtime export leaving: renderTemplate. RIGHT. The only source hunk is index.ts:88: export { renderTemplate, requireVars, htmlToText } from './template-engine.js' becomes export { requireVars, htmlToText } from './template-engine.js' plus a five-line [#25190] comment. No other export line moves; the type exports (TemplateLoader, EmailTemplateRow, …) and every other value export on the entry are byte-identical to the base.
  2. Nothing else reachable from the published surface still exposes the body-taking renderer. RIGHT. package.json at the head: exports carries only "." (dist/index.mjs / dist/index.js and their .d.ts), files is dist, README.md, CHANGELOG.md; the root tsup.config.ts builds entry: ['src/index.ts'] with splitting: false, so dist/ holds no separate template-engine.js and the exports map refuses a subpath import anyway. No package re-exports * from '@objectstack/plugin-email'; the one re-export elsewhere (packages/cli/src/commands/serve.ts:6808) names resolveEmailCapabilityArg, resolveDeploymentAppName, EmailCapabilityArg only. The two namespace importers in packages/cli (serve-auth-app-name.contract.test.ts, serve-stack-email-sms-door.contract.test.ts) read resolveDeploymentAppName / resolveEmailCapabilityArg only; examples/app-showcase/test/email-template-locale.test.ts imports createRegistryEmailTemplateLoader, DEFAULT_TEMPLATE_LOCALE. The function itself stays in template-engine.ts:109 (still exported from the module file, which is not a published path) and every in-package caller imports the module file, not the entry (email-service.ts:18, template-engine.test.ts:4, text-field-html-outlets.pin.test.ts:81).
  3. The stored-template doors keep rendering through the retired function. RIGHT. email-service.ts:1381 resolveAndRenderTemplate is untouched and still calls renderTemplate(row.body_html, …) at :1465 (html face, holes encoded), renderPlainTextTemplate for subject / body_text, htmlToText for the derived text; EmailService.renderTemplate (:1481) and sendTemplate (:1492) both go through it. The pin test's third case exercises both doors with a value carrying a b tag and expects the html face to carry it entity-encoded (&lt;b&gt;) and the subject verbatim, which is what that code does.
  4. The narrowing matches the cited rulings' letter. RIGHT.
    • Ruling 6335348115 item 6: retire renderTemplate (plugin-email) under ADR-0087 runtime-export-retired, BREAKING, at once, no staged window. The diff does that and nothing more. requireVars, htmlToText stay on the entry as the claim 6348488271 and ruling 6349343463 item 4 fix (setTemplateLoader, which the card body and claim say "stays", is an EmailService method at email-service.ts:638 and was never an entry export, so that line is vacuous and nothing is owed on it).
    • Ruling 6349343463 item 2: interpolate stays. At the head packages/services/service-messaging/src/index.ts:100 still exports interpolate; the diff touches no file under packages/services/. RIGHT.
    • Ruling 6349343463 item 4 and check-adr-0087-registration: no-metadata-surface reads a same-named interface member signature (IEmailService.renderTemplate) as a mention in code, because declaresLocally knows only top-level declarations — blocks #25190's renderTemplate retirement #25293 (6350996010, 6356337552): IEmailService.renderTemplate stays. The diff touches no file under packages/spec/; packages/spec/src/contracts/email-service.ts:341 still declares renderTemplate(input: RenderTemplateInput) returning a Promise of RenderTemplateResult, and the changeset's FROM → TO line points consumers at that very door (services.email renderTemplate({ template, data, locale }) / sendTemplate), which is the render-by-name door the placement rule can see. RIGHT.
    • Ruling 6349343463 item 4's premise ("while the gate exits 1 the half is not written") is met on this head rather than from the record: the Check Changeset job, whose step "Require an ADR-0087 disposition on a declared-breaking changeset" runs check-adr-0087-registration.mjs --base MERGE_BASE, concludes success on 0570b5e6, which is the three D9 predicates (retired-from-entry, no-metadata-surface with the fix(scripts): a same-named member declaration is a homonym in the ADR-0087 reference scan #25349 homonym reading, from-operands-named) holding in CI.
  5. The pin test pins the narrowing both ways. RIGHT. 'renderTemplate' in entry is false (a module-namespace in test, the right instrument for an absent export); the control names four exports that stay; the render case goes through the service doors. The dev's reverse check (base index.ts restored, case 1 red) is reported; I did not re-run it and do not need to: the first case is a direct read of the entry's export list, which the diff is.
  6. Readers of the retired name. RIGHT. My own sweep at the head: no renderTemplate imported from @objectstack/plugin-email anywhere in the tree (tests, ui/, examples/, docs/qa/**, scripts/** included); objectstack-ai/hotcrm at 94646738 has one email.renderTemplate({…}) call (test/flow-record-change.test.ts:181), the service method, unaffected. content/docs/automation/email-templates.mdx:14,224 and content/docs/releases/v17/17-1.mdx:170 name the service method renderTemplate({ template, data, locale }), so no doc page is falsified. CHANGELOG.md:1841 ("The exported renderTemplate() helper is still the HTML renderer") is a historical release entry, not a live claim.

Nothing in the diff is judged wrong. No accept set widens; the one accept set that narrows is the package entry's export list, by one name.

② Semver level

  • Changeset .changeset/25190-retire-render-template-export.md: '@objectstack/plugin-email': patch, title fix(plugin-email)!: …, a **BREAKING** (a runtime export is removed) banner, line-initial Clause-②: no (narrowing) and Metadata-protocol: none (byte-identical to the PR body's two lines), exactly one ADR-0087 marker not-required (runtime-export-retired @objectstack/plugin-email#renderTemplate) …, one FROM renderTemplate TO … line naming the stored-template door and the one-line fix, and an "Unchanged:" line naming IEmailService.renderTemplate, requireVars, htmlToText, the loader.
  • Repo rule (AGENTS.md Post-Task Checklist step 3): the level follows the metadata-protocol kind alone — none takes patch; "a non-protocol change, widening or breaking, ships patch and keeps its BREAKING banner and ADR-0087 disposition"; a breaking changeset carries its FROM → TO migration and exactly one ADR-0087 marker. This is also changeset levels: minor only when the metadata protocol changes (added / narrowed / semantic), patch otherwise; release notes grouped by what the reader must do (maintainer ruling A, 2026-10-21) #25105 ruling A as ruling 6335348115 restates it, and the shape ruling 6349343463 item 1 fixed for PR 1 (fix(service-messaging)!: retire renderNotification, the render export that takes a notification template body with no save moment #25285) and item 4 carried over to PR 2.
  • The diff publishes exactly what the changeset says: one runtime function leaves one published entry; no key of any metadata schema, no object definition, no stored shape and no spec contract moves, so Metadata-protocol: none is the right kind and patch the right level; (narrowing) is the right arm (an accept set — the entry's export list — shrinks); the D9 category is the right disposition (compiler-carried break, TS2305 at the consumer's own import, no ledger entry, no tombstone). Check Changeset success on the head is the gate's own reading of all of this. Level matches; Clause-②: line matches on both carriers. RIGHT.

③ Boundary flags

PR author: os-project-manager (the attribution marker in the body; the PR is relayed through objectstack-fleet[bot], per claim 6430890446 and the dev report 6431921813, session session_014LDnV6FyUqxjaBRSi5Kv1L).

Check-runs on 0570b5e6 at the time of this read (per gh api …/check-runs): success — Lint & Repo Gates, Lint · ESLint, Lint · PM dispatch-gates, Lint · repo & tooling gates, Lint · docs & code guards, Lint · CI/release/engine gates, the three Lint · scoped lanes, Type Check · source gates, Build Core, Test Core 7/8 and 8/8, Dogfood Regression Gate, Check Changeset (carries the ADR-0087 gate), Governed Surface Queue Guard, Check PR Size, Auto Label, Flag docs affected by code changes, Part-of PR must not also close its card, No other open PR may claim the same issue, No other open PR may claim the same single-writer path, The card this PR closes must claim this branch, filter. in_progress (9) — Test Core 1–6/8, Type Check · debt ledger, Type Check · consumer gates, Type Check · workspace. skipped — the UI lanes, Temporal Conformance, Build Docs, Dogfood Verify CLI, the sharded dogfood matrix, the opt-in tarball and 18.x harnesses. No check-run reads failure. The seat reads the nine in-progress lanes again before the queue; the dev's local tsc --noEmit + check:test-typecheck exit 0 on the package is the only reading of those nine so far.

Dev flags and open_questions, each answered or escalated:

  1. open_questions: [] — none on this PR; the one fork this card ever raised (6349141238) was ruled by 6349343463 letter A and its premise (item 4) is met on this head by the Check Changeset gate. Answered.
  2. "npm dependants: NOT MEASURED." Answered by the rulings, not by this review: ruling 6335348115 item 6 and ruling 6349343463 ② both carry "npm dependants unmeasured" as the known confidence gap and still rule "at once — no staged window", under the standing line 「暂时不考虑 v19,协议的调整原则上也是尽快,不考虑退役版本。」; ADR-0087 D9 names the compiler (TS2305 at the consumer's own import, with the changeset's FROM → TO line in the published CHANGELOG) as the channel that reaches every such consumer. The registry has no dependants index. Nothing further is owed on this PR; a production or npm reading, if one is ever obtained, comes back as its own card (the mail templates: a hole an author places in a template body may not be encoded for the context it lands in (reach not measured; detail withheld under the disclosure ruling) #25082 ruling's own disposition for unmeasured populations).
  3. Dogfood battery red (2 files, 10 tests), reported as main's red. The dev measured the same two files red with packages/rest/src and packages/qa/dogfood/test checked out from origin/main abb90460, and the diff touches no file they read. On this head CI's Dogfood Regression Gate concludes success, so the red does not even reproduce in CI on 0570b5e6. The out-of-scope finding (class a, carrier: whoever drives feat(plugin-approvals,rest,client): a record-anchored approval lock read, { locked } for every caller who can read the record #26361 / fix(auth,console): register mismatch is a confirm-field error; /register links privacy and terms #26291's follow-up, "noted, not filed") is not this PR's to file; escalated to the seat only as a reading — nothing is owed by this diff.
  4. Docs drift check (6431917025): index.ts yielded no anchor, so the pages are "not covered by this run"; the coarse fallback lists 6 package-mention pages. Answered by hand in ① item 6: every live renderTemplate mention in content/docs/** is the service method. The check-run concludes success.
  5. Deviations (branch is the harness-pinned claude/project-thread-s91v0o, recorded in the claim; a worker restart re-ran the full build; the PR was opened after the battery so the body is never PATCHed) — all answered by the claim and the report; no action.
  6. Skills-docs: line — ESCALATED to the seat. #26381 (b33dd25b, merged 2026-10-27T02:03:41Z — 56 seconds after this PR was opened at 02:02:45Z) now puts on main the rule that a PR whose Clause-②: carries (narrowing) owes the PR body a line-initial Skills-docs: updated here | follow-up owed — FILES | follow-up #N | none — REASON (.claude/skills/pm-dispatch/SKILL.md:313; the seat's review-checklist.md:18 reads "缺 ⇒ REWORK"). The body carries the substance in prose ("No skills/** reader"; the docs page names the service method, so it stays as written; the spec api-surface snapshots do not cover plugin-email) but not the line. The rule did not exist when the dev wrote the body, and the diff itself teaches nothing a skill or doc restates (the retired name appears in no skills/** file and in no live doc as an import). This is a body edit, not a code change, and does not bear on the narrowing's correctness: the seat decides whether to have the line added (Skills-docs: none — no skill or doc imports the retired name; content/docs/automation/email-templates.mdx names the service method) before ACCEPT. Not a contract-review FAIL.

Nothing in this review escalates to the maintainer: the retirement is the maintainer's own ruling, the sequencing was ruled under the delegation in 6349343463, and the premise that ruling bound PR 2 to is met on this head.

Implemented-by: claude/project-thread-s91v0o
Reviewed-by: session_0186vfjHHMsRXC9EUT9hTFMo

VERDICT: PASS


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对

ACCEPT · domain:server seat 2 · os-project-manager · session_0186vfjHHMsRXC9EUT9hTFMo · 2026-10-27T02:20Z · head 0570b5e6e5 · #25190

The maintainer's standing authorisation for landing reviewed PRs, verbatim: 「按照 pm-dispatch 规则复核过的都授权」.

  1. Shape: a draft against main, opening with Fixes #25190. This is the card's second and last PR; renderNotification left in fix(service-messaging)!: retire renderNotification, the render export that takes a notification template body with no save moment #25285. Clause-②: no (narrowing) and Metadata-protocol: none are line-initial and identical on the body and on .changeset/25190-retire-render-template-export.md (patch on plugin-email with the BREAKING banner, one ADR-0087 runtime-export-retired marker, and a FROM → TO line). The Skills-docs: line that docs(pm-dispatch,os-dev): a PR whose metadata-protocol kind is not none, or whose Clause-② carries (narrowing), owes a Skills-docs line #26381 now requires for a (narrowing) arm was missing because the rule merged 56 s after the PR opened. The seat added it to the body from the dev's measured line: none, meaning no skills/** reader exists and content/docs/** names only the services.email method. The head did not move.
  2. Contract review: the face is narrowing, so CONTRACT_REVIEW_TIER. The record is comment 6432072903 on this PR, on head 0570b5e6e5: PASS. Its one escalation is the Skills-docs: line, answered in 1.
  3. The seat's own reading:
    • Scope: the diff matches the corrected order, which is PR 2 only. One entry export line drops renderTemplate. requireVars and htmlToText stay. interpolate (service-messaging) and IEmailService.renderTemplate (spec) are untouched, per ruling 6349343463 items 2 and 4.
    • Changeset, sentence by sentence:
      • The author-time door list (os validate, os build, os lint, the runtime publish gate) matches the docblock at packages/formula/src/mail-html-hole-placement.ts:36.
      • "Nothing in this repository imported it from that entry" holds. Every renderTemplate import in the tree is from ./template-engine.js inside the package, and hotcrm calls only the service method.
      • "services.email still renders every stored email_template through it" holds: email-service.ts:18 imports it from the module file and :1465 calls it.
      • The package's exports map carries only ".", so no subpath reaches the module file.
  4. Gates: at this stamp every check-run on the head reads success or skipped (path-filtered UI, the dogfood matrix placeholder and opt-in harnesses). None reads failed or in progress. Check Changeset (which runs the ADR-0087 gate), Lint & Repo Gates, TypeScript Type Check, Test Core 1–8 and Governed Surface Queue Guard are green. Locally the dev reports the package suite 702/702, 65 of 65 derived gates exit 0, and the full dogfood battery run because the title has a bang.
  5. Accepted deviations:
  6. Landing: this seat runs pr_ready and then automerge_enable through the relay, confirms MERGED on both readings, and records the landing on plugin-email, service-messaging: retire the render exports that take a template body with no save moment (renderTemplate, renderNotification) — #25082 ruling F2 B3 #25190, which the merge closes.

Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 27, 2026 02:21
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 27, 2026 02:21
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 27, 2026
Merged via the queue into main with commit 92a0073 Oct 27, 2026
54 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-s91v0o branch October 27, 2026 02:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

2 participants