Skip to content

docs(agents): delete locale siblings when an English correction reverses a capability claim; record the type-check order - #322

Merged
os-zhuang merged 32 commits into
mainfrom
claude/pm-dispatch-objectos-ju9td1
Oct 7, 2026
Merged

os-zhuang merged 32 commits into
mainfrom
claude/pm-dispatch-objectos-ju9td1

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #256

Suggested title: docs(agents): criterion A for locale siblings, the type-check order, and no stale coverage count

维护者速读(草稿)

改了什么

为什么改

风险与代价(含回滚)

席位意见

建议合并。三处都是说明文字,和已落地的事实一致:第 3 步的判据逐字来自 #256 裁决 A,且 #290、#310、#315、#320、#321 已按这条判据执行过;type-check 的顺序与 main 上 apps/docs/package.json 一致(#313);覆盖数字去掉后不会再过期。本 PR 只改 AGENTS.md 一个文件,+5/−5,基于 main @ 84e747a,补丁与暂存分支逐字节相同。

你要做的

  • 读一下第 3 步的新句子,看判据的措辞是否就是你同意的意思;同意就合并。

What changed

Three commits, AGENTS.md only (+5 / −5).

  1. fe36dbf, Translation workflow step 3. A second exception sits next to retiring or renaming a page: an English correction that removes or reverses a capability assertion deletes that page's locale siblings in the same PR. Wording drift and number drift (a port number, a timing) stay with the translation pass, as step 2 says. The sentence links the ruling on [Decision] An English docs correction leaves its locale siblings asserting the corrected-away claim — #59 says delete them, the seat post says leave them, and #68 blocks the pass that would fix them #256 (comment 5989567068, letter A). Step 3's existing reasoning, that a translation of a page rewritten to assert something different is worse than none, is the justification. No new reasoning is added.
  2. fdc30ca, Commands. The npm run type-check line now shows the order apps/docs/package.json runs on main @ 94ce848 (next typegen && fumadocs-mdx && tsc --noEmit), with one sentence on why the order matters (CI type-check can fail with TS2306 ".source/server.ts is not a module": next typegen exits while fumadocs-mdx's un-awaited regeneration is still writing .source #311).
    • This is a tighter rewrite of the staged line 4afa327. That line applied cleanly but ran to five sentences.
    • The mechanism was re-read from the installed fumadocs-mdx 15.0.7: in dist/next/index.js, createMDX() calls init(isDev, core) without awaiting it.
  3. f49f796, Traditional Chinese section. "Coverage tracks Simplified exactly (62 of 79 pages today). The 17 without …" now reads "Coverage tracks Simplified exactly. A page without a Simplified sibling has no Traditional one either, so it is never advertised in the sitemap or an hreflang cluster — it simply renders English."
    • On 94ce848, git ls-files counts 79 English pages and 48 zh-Hans siblings.
    • The rule stays; only the count, which nothing keeps current, is removed.
    • The bullets on either side (retiring a page prunes its Traditional file; committed output, not on-the-fly conversion) read unchanged.

Why

Checks

Measured on f49f796. git status was empty and the merge-base with origin/main is 94ce848.

  • Ownership gate, with the workflow's argv (git diff --name-status --no-renames origin/main...HEAD gives one line, M AGENTS.md):
    • --actor "objectstack-fleet[bot]", variable unset as it is live: exit 0, ⚠ TRANSLATION_BOT_LOGIN is not set — ownership is not enforced yet. … This PR touches 0 translation artifact(s) and 1 other file(s).
    • The same, with TRANSLATION_BOT_LOGIN=placeholder-translator: exit 0, ✓ 1 file(s) changed, no translation artifacts touched.
    • Control, actor = the placeholder translation account: exit 1, ✗ translation PRs may only touch translation artifacts.
    • --self-test: exit 0, ✓ self-test: 21 case(s), …
  • Governed predicate, objectstack scripts/pm/check-governed-merges.mjs --test AGENTS.md --additions 5 --deletions 5 (objectstack @ ba5927f7): exit 3, ⛔ GOVERNED — a human merge is the review record for this PR, landing tier: H(人合), size: 10 changed line(s) (+5 / -5) ≤ 5000.
  • Control-byte scan, grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]' over the diff and over AGENTS.md: grep exit 1 both times (no match). A positive control holding a DEL byte matched (exit 0).
  • Order check: the type-check script read from apps/docs/package.json on origin/main appears verbatim as a code span in the new line (1 hit). The stale-count grep (62 of 79|17 without) on AGENTS.md returns no match.
  • Not applicable, with reasons:
    • objectos .github/scripts has no governed-prose, skill-lint or line-ratchet gate, and none of its scripts reads AGENTS.md as input.
    • objectstack's check-governed-prose, check-skill-id-lint and check-skill-line-ratchet locate their files from their own repo root, so they cannot read this file.
    • No package changed, so no build or test is owed locally. CI's build job runs on this PR anyway.

Acceptance notes

  • The gate admits criterion-A deletions once it is enforced. With TRANSLATION_BOT_LOGIN set, a synthetic list (M English page plus three D locale siblings) exits 0 with 3 translation artifact(s) deleted, none added or modified. The control with a locale M exits 1. The gate's header and failure text name only retire/rename as the reason to delete. That stays true, but it no longer covers every case; left alone, outside this PR's surface.
  • Ownership & freshness will not run on this PR. Its paths filter does not include AGENTS.md, so the ownership result above is local only. CI (build, Node floor) has no path filter and runs.

Pushed head

86fd18c on claude/pm-dispatch-objectos-ju9td1, a fast-forward with no force. It starts at the remote branch head a8ce2ea (#321), merges origin/main @ 84e747a (after the merge the diff against main is empty), and cherry-picks fe36dbf, fdc30ca and f49f796. git diff origin/main 86fd18c is byte-identical to the staged branch's diff. Governed: the maintainer merges this PR; the seat does not.


Generated by Claude Code

objectstack-fleet Bot and others added 30 commits October 6, 2026 10:36
…ds or fewer

Adds a `seoTitle:` frontmatter line to every English page whose built
`<title>` read as one or two words plus the ` | ObjectOS` suffix, so the
tab/result title carries the terms a reader searches for while the H1,
sidebar and breadcrumb keep the short noun (#166's mechanism).

- 67 pages: each gains exactly one line; no `title`, `description` or
  body line changes.
- Every title leads with the page's own specific term, lifted from its
  description and headings, and renders at 52–60 characters including the
  suffix (measured on the built HTML).
- The three duplicated titles (Approvals, Dashboards, Notifications —
  each used by a build/configure page and a use page) are now distinct.
- English only. Locale siblings are translation artifacts that a
  non-translator commit may not modify (AGENTS.md, Translation workflow;
  check-translation-ownership.mjs); the translation pass carries the new
  key over, and the output report lists the 163 siblings now missing it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeA1nwBz1ohH65dvffUGKr
…AQ headings, title-weighted per-locale search, consistency pass

- Light-mode muted foreground to hsl(0 0% 40%); code comments recoloured in
  both shiki themes.
- Tables get an always-drawn scrollbar and a scroll-driven trailing fade.
- FAQ and License FAQ questions become headings.
- /api/search builds one locale's index on that locale's first search and
  weights title > heading > text; check-search-locales gains own-title-buried;
  smoke-docs asks /api/search in every locale with a nonce control.
- Consistency: one data-residency table, one license-validation sentence,
  ObjectSchema.create, "license" spelling, Configure title, glossary order plus
  AI seat and Position, logo to the docs home, a translated llms.txt example,
  three unsourced configure/ai claims removed (with their locale siblings),
  release-following lines pointed at a populated feed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeA1nwBz1ohH65dvffUGKr
…comments

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeA1nwBz1ohH65dvffUGKr
…ix apiMethods primitives

The Views page declared views inside a defineObject call under an
object-level `view` key. ObjectStack provides no defineObject, and
ObjectSchema.create rejects `view` as an unknown key. Its views are a
defineView container ({ list, listViews, form, formViews }, each view
bound through `data`) registered on the stack with `views: [...]`, which
both samples now show; both parse with @objectstack/spec 17.6.0.

The REST API page's allowed apiMethods values drop the eight retired ones
the spec strips at parse.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeA1nwBz1ohH65dvffUGKr
…ype-check

`next typegen` loads next.config.mjs, and fumadocs-mdx 15.0.7's createMDX()
starts init() without awaiting it (dist/next/index.js:14-20). init rewrites
every .source/*.ts with fs.writeFile (dist/core-DlDe_Eze.js:232-236), which
truncates first. typegen ends in process.exit(0), so it can exit inside that
window and leave .source/server.ts empty for tsc: TS2306, CI run 37478051451.

Running the fumadocs-mdx CLI after typegen makes the CLI, which awaits its
writes, the last writer before tsc. typegen does not read .source.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeA1nwBz1ohH65dvffUGKr
…ries, zh-Hant 404, Open-in links follow the page shown

- patches/fumadocs-ui@16.8.12.patch: the nine accessible names fumadocs-ui
  16.8.12 hard-codes in English (Open Search, Toggle Theme, Open/Collapse
  Sidebar, Copy Anchor Link, Copy/Copied Text, Toggle Menu, and Radix's
  "Main") read from its i18n context with the old literal as default. Eight
  keys are a backport of upstream 16.9.0's own names; lib/ui-text supplies
  all nine through RootProvider in every locale.
- app/[lang]/docs/layout.tsx: page-tree entries (sidebar, breadcrumb,
  prev/next footer) for pages a locale has no translation of carry
  lang="en", using the docs page's own translatedLocales detection.
- app/not-found.tsx: the 404 copy moves into lib/ui-text (notFound), so the
  zh-Hant string is generated from zh-Hans by gen-zh-hant and checked by
  --check like every other Traditional string.
- Open in ChatGPT / Claude on a translated page sends the assistant to the
  translated page itself; English pages and fallbacks keep the English .mdx.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeA1nwBz1ohH65dvffUGKr
…pec 17.7.0

views.mdx: every list-view fragment carries its required top-level
columns, fontWeight is a string, the list view types table states the
required keys the spec declares, and each fragment says what it omits.

flows.mdx: every sample is rewritten from the old trigger/steps shape to
FlowSchema's nodes and edges. Email goes through a notify node with
channels: ['email']; requires lists automation and triggers.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeA1nwBz1ohH65dvffUGKr
…ative GitHub icon, code blocks off the landmark list, a localized Open-in prompt

axe 4.14.0 reported four failures on every docs page in every locale,
English included (#308):

- landmark-one-main: the docs layout has no main landmark. DocsPage passes
  its other props to the article it renders, so the docs page sets
  role="main" there; no patch needed.
- label-content-name-mismatch: the language switcher shows the current
  language but was named "Choose a language" only. It is now named
  "English — Choose a language", "Deutsch — Sprache wählen", visible text
  first, both halves from the i18n context.
- svg-img-alt: the GitHub icon was an svg role="img" with no name inside a
  link already named "GitHub"; it is aria-hidden now.
- landmark-unique: every code block's scroll viewport was an unnamed
  role="region". The role goes; tabIndex 0 stays for keyboard scrolling.

The last three are hunks added to patches/fumadocs-ui@16.8.12.patch; its
header says why each is a hunk and not a slot, and what an upgrade must
re-check. None of the three is fixed upstream as of 16.16.2.

The "Open in ChatGPT / Claude" prompt sentence was English in every locale.
It is now the ui-text key pageActionsOpenInLLMPrompt, upstream 16.9.0's key
name, placeholder and English, translated in six locales and generated for
zh-Hant. ui-text's table() now also holds every locale's placeholders to
English, so a translation that drops {url} fails the build.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeA1nwBz1ohH65dvffUGKr
…ree entries

#298 and #305 made two promises about every localized docs page that no
gate checked afterwards: no control is named in English, and every
page-tree entry for an untranslated page carries lang="en". The locale
surface gate now reads them off the prerendered HTML under
apps/docs/.next/server/app/<locale>/, script bodies (the RSC payload)
skipped:

- english-chrome-name: an accessible name (aria-label, title, alt,
  placeholder, svg title, .sr-only text) on a localized page that is one of
  the English pages' names, outside lang="en". The English set is read off
  the built English pages, minus GitHub and www.objectos.ai.
- untranslated-entry-unmarked: a sidebar item or previous/next card for a
  page the locale has no source file for, whose text does not resolve to
  lang="en". The oracle is the content tree, not the app's detection.
- translated-entry-marked-english: the over-marking direction.

Guards keep it from passing over nothing (a page missing from a locale's
build, no English name to compare, no entry of a kind recognised in a
locale), and a live control feeds both #305 shapes, built from the run's
real oracle values, through the same reader on every run. Ten self-test
cases, and the control shown red with a reader blinded to names or to lang.

On the HTML main built at cec227a it reports 6239 English names and 5974
unmarked entries; on #305's tree, 0 and 0. No ci.yml change: the existing
Locale surface step runs the gate after the build, and pnpm turbo run test
runs its self-test.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeA1nwBz1ohH65dvffUGKr
Below 1280px fumadocs-ui 16.8.12 shows the page's table of contents as a
bar rendered in a <header> outside every sectioning element, so the page
had two banner landmarks: the site header (#nd-subnav) and this bar. axe
4.14.0 at 390px reported landmark-unique and landmark-no-duplicate-banner on
all 48 runs of the #308 sample (8 sections, en/zh-Hans/de, light/dark), on
the tree that already carried the other #308 fixes. The bar is a disclosure
for the page's headings, so the patch renders it as a <div>; no CSS selects
header by element, and the 390px screenshots do not change. Upstream 16.16.2
still renders it as a <header>.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeA1nwBz1ohH65dvffUGKr
…e inside an English body

#305 localized the names of the heading-anchor and code-copy buttons. On
a fallback page both buttons sit in the page body, which #298 marks
lang="en", so "Ankerlink kopieren" was read with English rules: WCAG 3.1.2,
the inverse of what #305 fixed. On main at cf449fa that was 520 + 115
names per Latin-script locale over 55 fallback pages, and 336 + 58 in
zh-Hans and zh-Hant over 31.

Both buttons now take locale from the useI18n() they already read and
render it as their own lang (patches/fumadocs-ui@16.8.12.patch, the two
#305 hunks). On a page in the route locale this repeats what html lang
says; inside an English body it keeps the name in its own language.

check-locale-surface.mjs gains the inverse rule,
localized-name-marked-english: one of a locale's own names (read off its
built pages, the names that resolve to the locale, minus the English set)
inside a lang="en" region with no lang of its own fails. Two self-test
cases (red as #305 shipped it, green through an inherited lang), the
fixture body now carries a localized anchor button with its own lang, and
the live control feeds the inverse shape too, shown red with a reader
blind to lang on names.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeA1nwBz1ohH65dvffUGKr
The "nothing built" guard in check-locale-surface.mjs fired artifact-missing
only when no locale directory held any HTML at all. The legal pages and the
locale roots live in the same directories, so a build (or a fixture tree)
holding them but no docs page fell through to one docs-page-html-missing per
page plus the blind-reader guards. #312 adds legal-page fixtures to every
self-test case, and with them this file's "docs pages not built" case read
exactly that way. Measured on this tip with #312's own two commits applied in
memory (git merge-tree --merge-base 4da46c5): before this change 1 self-test
case failed, after it 48 cases over 25 rules pass. The guard now asks whether
any <locale>/docs page was built.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeA1nwBz1ohH65dvffUGKr
…ce; zh-Hant generated from zh-Hans

- privacy and terms on de, ja, es, fr and ko: the English entry is marked
  lang="en" (title, date, body, back link) and introduced by the #298 notice
  (ui-text notTranslated) in the route locale. en and zh-Hans render as before.
- The zh-Hans entry of each page moves, unchanged, into a zh-Hans.json beside
  it; gen-zh-hant converts it to zh-Hant.json like lib/ui-text, so
  /zh-Hant/privacy and /zh-Hant/terms show Traditional text and gen-zh-hant
  --check covers it. contentLocales, hreflang and the sitemap gain zh-Hant.
- check-locale-surface: STATIC_PAGES lists zh-Hant, and three rules read the
  built legal pages (legal-english-unmarked, legal-translation-shows-english,
  legal-page-unread), with self-test cases.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeA1nwBz1ohH65dvffUGKr
…econd main

HomeLayout already renders main#nd-home-layout around its header and the page,
so the page's own main was a nested, duplicate landmark on /privacy and /terms
in every locale (axe: landmark-no-duplicate-main, landmark-main-is-top-level,
landmark-unique). Same classes, so nothing moves on screen. The
check-locale-surface legal fixture now mirrors that structure.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeA1nwBz1ohH65dvffUGKr
…capability claim

Rule 3 ended "When in doubt, delete rather than leave behind", and the
Retiring a page section told authors never to leave a translation behind
for a page "rewritten to say something different". Read literally, both
delete a whole translated page over a changed port number, which
AGENTS.md step 2 and the new step 3 say stays with the translation pass.

Both now state the ruled line: an English correction that removes or
reverses a capability assertion deletes the page's locale siblings in
the same PR, and wording and number drift stay with the pass. Rule 3
links the ruling. GUIDE_REV is not bumped: no existing translation
output becomes invalid.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeA1nwBz1ohH65dvffUGKr
…ack/spec 17.7.0

First half of the docs code-sample family close-out (#316): the samples on
eight English pages now parse with @objectstack/spec 17.7.0, the npm latest.

- workflows: the XState-style StateMachineConfig left the spec. A workflow
  is the `state_machine` validation rule on the object, with `requiredWhen`
  for "no resolved case without a resolution". The side-effect flow gets
  its labels and node configs. automation/index stops promising events
  and guards.
- approvals: labels on the start and end nodes, real `update_record`
  configs, and `resolveAs` moved onto the `expression` approver.
- actions: `Action` from `@objectstack/spec/ui`; the confirm question
  moves from `confirmText` to `description`. There is no flow node that
  calls an action and no view `actions` key, so the flow-step surface goes,
  placement is the action's `locations`, and a list view names
  `rowActions` / `bulkActions`.
- data/index: the stack namespace prefix, `inlineHelpText`, a `format` rule
  in place of field `pattern`, typed validation rules, the real ownership
  values and lifecycle shape, and no `decimal` type.
- relationships, formulas, validation-rules: `Field.masterDetail` and
  `Field.lookup` take the reference first, `Field.decimal` does not exist,
  option placeholders become real options, and fragments say what they are.

Locale siblings follow ruling A of #256: deleted for workflows,
automation/index, actions and data/index (18 files), where a capability
assertion is removed or reversed; kept where the change is code shape only.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeA1nwBz1ohH65dvffUGKr
…17.7.0

Second half of the docs code-sample family close-out (#316), on 14 more
English pages.

- cel: the six one-liners become real slots (a formula field, a `script`
  rule's `condition`, `visibleWhen`, a start node's `condition`, a
  schedule's `expression`, a notify node's plain-text title), and the
  "where each tag is used" table names keys that exist. `tmpl` is not a
  notification slot: `NotifyConfigSchema.title` refuses it.
- agents: no `knowledge` block (removed in 17.0.0), memory is
  `longTerm.enabled` / `maxEntries` / `reflectionInterval`, and flows reach
  an agent through a `type: 'flow'` action.
- data-sources: a flat postgres config, no inline password (the secret is
  named in `external.credentialsRef`), `defineDatasource()`, a complete
  manifest, and a declared second datasource.
- apps: `mobileNavigation` was removed in 17.0.0. dashboards:
  `refreshIntervalSeconds`, and no `certified` measures.
- quickstart, record-access, rest-api, forms, pages, field-types, the two
  permission pages, objectql: builder signatures, required `fields`,
  real options, `requiredWhen`, and fragments that say what they are. The
  cel and objectql type signatures carry the doc-sample opt-out marker,
  an MDX comment that renders nothing.

Locale siblings follow ruling A of #256: deleted for agents, cel, apps and
dashboards (18 files), where a capability assertion is removed or reversed;
kept where the change is code shape only.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeA1nwBz1ohH65dvffUGKr
`.github/scripts/check-doc-samples.mjs` reads every ts/js block on every
English page under content/docs and parses it with @objectstack/spec, as
#307 did by hand: statements evaluated as published with only TypeScript
syntax removed, every spec constructor call a parse, imports checked
against the entry point (type imports through the TypeScript compiler),
every flow's builtin nodes against their executor contracts, and a stack's
`requires` judged with the flows on its page. A fragment's first comment
says what it is, and the gate parses it inside the smallest whole it
belongs to. A block that is not a spec sample is N/A; a block that matches
no rule fails.

An MDX comment `{/* doc-sample: skip — why */}` right before a fence opts
one block out, for a counter-example or a type signature. It renders
nothing and is stripped from the llms bodies.

The spec is pinned exactly in `.github/scripts/doc-samples/` with its
npm lockfile, outside the pnpm workspace: as a devDependency of
tools/ci-scripts it re-resolved fumadocs-core's optional zod peer from
4.4.3 to 4.6.5 while fumadocs-mdx kept 4.4.3, two zod copies in the docs
build. CI installs it with `npm ci --prefix`, and Dependabot gets its own
entry for that directory, so a spec release that newly refuses a sample
turns its own bump red.

The gate's `--self-test` (51 cases, a pass and a refusal for each of the
22 fragment kinds) joins the runner in tools/ci-scripts. The CI step sits
next to the zh-Hant check, before type-check.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeA1nwBz1ohH65dvffUGKr
…ses a capability claim

Step 3 of the translation workflow now names a second exception beside
retiring or renaming a page: an English correction that removes or
reverses a capability assertion deletes that page's locale siblings in
the same PR. Step 3's own reasoning already covers it, since a stale
translation of such a page renders a claim the English no longer makes.
Wording and number drift stay with the translation pass, per step 2.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeA1nwBz1ohH65dvffUGKr
claude added 2 commits October 7, 2026 04:16
The Commands line still showed the old order. It now shows the order
apps/docs/package.json runs and the one-sentence reason: next typegen
can exit while createMDX() is still rewriting .source/* unawaited, so
the awaited fumadocs-mdx CLI must be the last writer before tsc.

A tighter rewrite of the staged line 4afa327, which applied cleanly
but ran to five sentences.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeA1nwBz1ohH65dvffUGKr
The Traditional Chinese section said Simplified covers "62 of 79 pages
today" and "the 17 without". The tree now has 48 of 79, and the figure
had already moved twice with nothing gating it. The bullet keeps the
rule (coverage tracks Simplified exactly; a page without a Simplified
sibling renders English and is never advertised) and drops the count.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeA1nwBz1ohH65dvffUGKr
@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 7, 2026 04:20
@objectstack-fleet
objectstack-fleet Bot requested a review from os-zhuang October 7, 2026 04:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants