Skip to content

feat(spec)!: flow 节点 config 契约收紧 —— schemaless 那三个从来没有过键闸门(#4001 批 9) - #4925

Merged
xuyushun441-sys merged 2 commits into
mainfrom
claude/issue-4001-automation-batch9
Aug 3, 2026
Merged

feat(spec)!: flow 节点 config 契约收紧 —— schemaless 那三个从来没有过键闸门(#4001 批 9)#4925
xuyushun441-sys merged 2 commits into
mainfrom
claude/issue-4001-automation-batch9

Conversation

@xuyushun441-sys

Copy link
Copy Markdown
Contributor

Part of #4001

按 2026-08-03 11:42Z 维护者裁决派发的 automation/ 首批。三个文件、14 个 strip 站点归零,automation/ 剩余 strip 67 → 53(可授权 41 → 27),台账三行按反向闸门要求删除、表头算术已配平。

⛔ 刻意不动:FlowNodeSchema.config 槽位本身。ADR-0018 让 node.type 对插件开放,插件 executor 自带 configSchema,关掉槽位等于关掉那个扩展点。收紧的是槽位里面的每类型契约。


一、这批里唯一不是「第二道门」的那三个

其余收紧批次的常见形态是:某处已经有守卫,schema 收紧是补上另一扇门。这批的前两个文件确实如此 —— notify / http / CRUD 四件套 / screen / map 都是描述符带 configSchema 的内建,registerFlow() 早就按描述符硬拒未声明键(#4277)。

script / subflow / decision 不是。 validateNodeConfigKeys 从描述符的 configSchema 推导「已声明集合」,而这三个类型按设计不发布 configSchema,所以那个遍历按构造跳过它们(engine.ts 里写着这条豁免)。也就是说在这次收紧之前:

script / subflow / decision 的整个 config 面,在任何一层都没有未知键强制#4343 加的执行期 parse 只查类型与必填,其余一律被 .strip 静默删掉。

这正是 #4001 第二类发现(「bespoke 守卫只守一扇门」)最纯粹的形态:守卫是为它作者面前那扇门写的,而它结构上覆盖不到的那一类,恰好就是没有第二扇门的那一类。所以对这两个节点(script/subflow#4343 之后确实在执行期被 parse)这不是重复检查,是它们的第一道检查

decision 仍是 export-only,收紧只绑定在 tsc、published JSON Schema 和 objectui 对账三处。仍然收 —— 因为战役反复证明:一个留开的形状会长出一个测试、一张表单和一份 fixture 去断言那份开放,再关就是迁移而不是编辑。

二、策展是量出来的,不是想出来的

每一条 guidance / aliases 都先过了一次全仓 AST 普查:630 个真实 flow 节点载荷(examples / 平台应用 / 测试 / docs 代码块 / 转换 fixture),按节点类型收集 config 的顶层键与 fields[]conditions[]options[] 的子键,再和声明集合求差。没有任何真实载荷反驳的条目才留下。

最难的一条,和战役的第 7 条发现同形。

decisionconfig.condition(单数)离 conditions 只有 1 个编辑距离,纯距离建议器会自信地提议改成复数。照做是更坏的结果:节点声明 conditions 同时出边带 condition,就是「节点先选一支、这支的边再判一次」的双重声明,#4414 就是为这个开的。所以这条 suppress 掉改名,改说机制:分支活在出边上。

而在 decision 的分支项上,同一个词的判决相反 —— 谓词槽真的叫 expression,且 FlowEdgeSchema 早就反向声明了 expression → condition 的别名。所以这里给 condition → expression一个词、两个面、两个方向都声明。

其余成串的条目:

条目 依据
notify to/subject/body/url/source ADR-0087 D2 flow-node-notify-config-aliases
CRUD object/filters/fieldValues 两条转换 + #2419(PD #12 的样板案例,cfg.fields ?? cfg.fieldValues 当年被明确否掉)
CRUD recordId 普查测出:仓库自己的 flow fixture 在 get/update/delete 上都写过它,而没有任何 executor 读过。在 delete_record 上,一个「唯一的约束条件根本不被读」的删除节点就是 #3810,穿着一个读起来像约束的键。编辑距离够不到任何已声明键,不给处方就只能报个键名
update_record / delete_record outputVariable 一个有据可查的「没有」(#4045 专门记下来「免得有人再追一遍」)。恰恰因为五个兄弟契约都声明了它,它才是这两个形状上最可能被写错的键
screen visibleIfvisibleWhenobjectobjectName #3528screen 不在 flow-node-crud-object-alias 的类型集合里,四个编辑距离也够不到,所以只有别名表能说这句话
subflow flowtimeoutMs 转换;以及一个跨层指向 —— subflow 步骤的超时是引擎的节点级闸门,键在 FlowNodeSchema.timeoutMs
script functionNameinput 转换。input 的处方额外声明:单数在 connector_actionconnectorConfig.input是规范的,别去"修"它

http 刻意没有策展表:普查没测到任何退役拼法或跨面近似,而两个可能的手滑(timeouttimeoutMsheaderheaders)编辑距离本来就够得到 —— 这两条现在有测试钉着,一旦够不到了,注释就是错的、就欠一条条目。凭空造条目正是这场战役有一批一次性发出四条自信写错处方的原因。

script 的五个 retiredKey 墓碑不需要条目:墓碑本身更强(顺带把类型变成 never),而 strictObject 已经把不可写的键排除出候选表(第 12 条发现)。有测试钉住这一点。

三、ADR-0087:实测「否」

不是靠读代码下的结论。把三个示例 app 的 build 产物(dist/objectstack.json,含 ADR-0031 region 递归)里每一个 flow 节点的 config 拿去按新契约 parse:

flow nodes walked: 160 — with a批-9 contract: 52
UNKNOWN-KEY rejections introduced by 批 9: 0
pre-existing non-unknown-key parse failures: 0

先证红再信绿:往 app-todo 的产物里注入一个 negativeControlKey,探针立刻报红并打出完整拒绝信息,随后产物已还原。

三个 app 的 objectstack validate 全过(✓ Validation passed,showcase 29 flows)。

四、仪器纪律 —— 这批让四把尺各红过一次

怎么让它红的 结果
check:strictness-ledger 反向闸门 收紧后不删台账行 精确报出三行 + 表头该减多少 ✅
builtin-node-form-zod-ledger.test.ts(任务书点名要用作证据的那个) MapConfigSchema 加一个 probeOnlyDriftKey map: read by the executor but absent from the designer form: expected ['probeOnlyDriftKey'] to deeply equal []
本 PR 新增的 strict 断言 MapConfigSchema 换回 z.object 两条 strict 专属断言红,其余 23 条绿(说明它们钉的确实是 strict,不是别的) ✅
本 PR 新增的 guidance 断言 摘掉 DECISION_KEY_GUIDANCE expected '…' to contain '#4414'
ADR-0087 探针 往产物注入未知键 报红并打出拒绝信息 ✅

⚠️ 顺带被这条纪律救了一次:做变异探针时跑过一次 build,authorable-surface.json 把探针键写了进去automation/MapConfig:probeOnlyDriftKey)。已 git checkout 复位后重新生成 —— 记在这里因为它是「变异测试的副作用会渗进生成物」这个具体的坑。

五、objectui 跨仓

objectui 的 flow-node-config.spec-reconciliation 测试比的是 .shape键集合,不是 parse,所以 strict 对它不可见。批 9 一个键都没动。 这个不变量现在有一条本仓测试钉着(SubflowConfigSchema / DecisionConfigSchema / DecisionConditionSchema.shape 精确键集),理由写在测试里:失败该落在做修改的那个仓库,而不是我们改不了的那个。

另:objectui 的 decision 面板把单数 condition 做成 legacy-gated(只渲染存量、不供新作者写),和本 PR 给 condition 的判决完全一致 —— 两边都说「它不在契约里」。

六、散文也一起搬了门

三个文件的 module JSDoc 里都有一段「未知键是注册层的事,这里只 strip」。那句话现在不对了,已就地改写并说清两扇门各自的分工(注册那扇仍然是先到的、信息更全的那一扇 —— 它会按描述符 JSON Schema 递归下去,这才是它能抓到 fields[0].visibleIf 的原因)。

FLOW_NODE_UNKNOWN_KEY_GUIDANCE(engine 里注册门带的策展表)保留不动。按战役的结论:bespoke 守卫里值钱的从来不是检测(默认一翻就免费泛化),是那句话 —— 所以那句话被抄到新门上,而不是把旧门拆了。


验证

pnpm --filter @objectstack/spec test         297 files / 7410 tests  ✅
pnpm --filter @objectstack/spec typecheck    tsc --noEmit clean      ✅
pnpm --filter @objectstack/spec check:generated                 8/8 ✅
pnpm --filter @objectstack/spec check:strictness-ledger
  ✓ 67 file(s) across 5 triaged director(ies)
  ✓ 48 open file(s) / 311 strip site(s)   (合并前 51 / 325)
pnpm --filter @objectstack/service-automation test   55 files / 662  ✅
pnpm --filter @objectstack/lint test                 54 files / 970  ✅
pnpm --filter @objectstack/metadata-protocol test    281 tests       ✅
examples/{app-crm,app-showcase,app-todo} validate                    ✅

合并 origin/main(8 commit,未触及 packages/spec/src)后按 os-regen 四步协议同步:每个 merge=os-regen 路径先 git checkout origin/main --,再从合并后的源整体重生成(不做文本合并)。spec-changes.json / authorable-surface.json / json-schema.manifest.json / api-surface{,-signatures}.json / protocol-upgrade-guide.md 重生成后与 origin/main 逐字节相同 —— 这就是「兄弟 PR 的条目仍在」的断言。只有本批拥有的三张 reference 页有差异。上述验证全部是合并后重跑的读数。

范围外发现(已按 PD #10 建单,未在本 PR 修)

相关

🤖 Generated with Claude Code

https://claude.ai/code/session_01Ehu85kbvMcrNTUJjwxvLJ9


Generated by Claude Code

claude added 2 commits August 3, 2026 16:19
…4001 批 9)

Fourteen strip sites across the three automation node-config files close —
the first `automation/` wave of the 2026-08-03 "necessary-and-complete"
ruling. `automation/` remaining-strip: 67 → 53 (authorable 41 → 27).

- io-node-config: NotifyConfig, HttpConfig
- builtin-node-config: the CRUD quartet, Screen (+ field item + its options),
  Map
- schemaless-node-config: Script, Subflow, Decision, DecisionCondition

The deliberately-open `FlowNodeSchema.config` SLOT is untouched (ADR-0018
keeps `node.type` open for plugin executors); what closes is the
per-node-type contract inside it.

For `script` / `subflow` / `decision` this is the FIRST unknown-key gate,
not a second one: `registerFlow()`'s #4277 rejection derives its declared
set from a descriptor `configSchema`, and the schemaless class publishes
none — so that walk skips them by construction.

Curation is measured, not assumed. Every guidance/alias entry was checked
against a repo-wide AST scan of 630 real flow-node payloads before it was
written, and the campaign's finding 7 decided the one hard case: on a
`decision`, `config.condition` is NOT renamed to `conditions` (one edit
away, and taking that advice produces the double-declaration #4414 was
filed for) — the mechanism is named instead. On a decision BRANCH the same
word does rename, to `expression`.

ADR-0087: no conversion needed. 160 flow nodes across the three shipped
example apps were parsed against the new contracts — 52 carry one — with 0
unknown-key rejections, and all three `objectstack validate` runs pass.
@vercel

vercel Bot commented Aug 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 3, 2026 4:30pm

Request Review

@github-actions github-actions Bot added size/xl documentation Improvements or additions to documentation tests tooling labels Aug 3, 2026
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/spec.

106 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/agents.mdx (via @objectstack/spec)
  • content/docs/ai/skills-reference.mdx (via @objectstack/spec)
  • content/docs/ai/skills.mdx (via @objectstack/spec)
  • content/docs/api/client-sdk.mdx (via @objectstack/spec)
  • content/docs/api/environment-routing.mdx (via @objectstack/spec)
  • content/docs/api/error-catalog.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-client.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-server.mdx (via @objectstack/spec)
  • content/docs/api/index.mdx (via @objectstack/spec)
  • content/docs/automation/approvals.mdx (via @objectstack/spec)
  • content/docs/automation/connectors.mdx (via @objectstack/spec)
  • content/docs/automation/flows.mdx (via @objectstack/spec)
  • content/docs/automation/hook-bodies.mdx (via packages/spec)
  • content/docs/automation/hooks.mdx (via @objectstack/spec)
  • content/docs/automation/index.mdx (via @objectstack/spec)
  • content/docs/automation/webhooks.mdx (via @objectstack/spec)
  • content/docs/automation/workflows.mdx (via @objectstack/spec)
  • content/docs/concepts/architecture.mdx (via @objectstack/spec)
  • content/docs/concepts/design-principles.mdx (via packages/spec)
  • content/docs/concepts/index.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-driven.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-lifecycle.mdx (via packages/spec)
  • content/docs/concepts/north-star.mdx (via @objectstack/spec)
  • content/docs/data-modeling/analytics.mdx (via @objectstack/spec)
  • content/docs/data-modeling/drivers.mdx (via @objectstack/spec)
  • content/docs/data-modeling/external-datasources.mdx (via @objectstack/spec)
  • content/docs/data-modeling/field-types.mdx (via @objectstack/spec)
  • content/docs/data-modeling/fields.mdx (via @objectstack/spec)
  • content/docs/data-modeling/formulas.mdx (via @objectstack/spec)
  • content/docs/data-modeling/index.mdx (via @objectstack/spec)
  • content/docs/data-modeling/objects.mdx (via @objectstack/spec)
  • content/docs/data-modeling/queries.mdx (via @objectstack/spec)
  • content/docs/data-modeling/schema-design.mdx (via @objectstack/spec)
  • content/docs/data-modeling/seed-data.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation-rules.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation.mdx (via @objectstack/spec)
  • content/docs/deployment/cli.mdx (via @objectstack/spec)
  • content/docs/deployment/troubleshooting.mdx (via @objectstack/spec)
  • content/docs/deployment/validating-metadata.mdx (via @objectstack/spec)
  • content/docs/getting-started/build-with-claude-code.mdx (via @objectstack/spec)
  • content/docs/getting-started/common-patterns.mdx (via @objectstack/spec)
  • content/docs/getting-started/examples.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-reference.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx (via @objectstack/spec)
  • content/docs/getting-started/your-first-project.mdx (via @objectstack/spec)
  • content/docs/kernel/cluster.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/auth-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/cache-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/data-engine.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/index.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/metadata-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/storage-service.mdx (via packages/spec)
  • content/docs/kernel/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/email-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/queue-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/sharing-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/sms-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/storage-service.mdx (via packages/spec)
  • content/docs/kernel/services-checklist.mdx (via @objectstack/spec)
  • content/docs/kernel/services.mdx (via @objectstack/spec)
  • content/docs/permissions/authorization.mdx (via @objectstack/spec)
  • content/docs/permissions/permission-sets.mdx (via @objectstack/spec)
  • content/docs/permissions/permissions-matrix.mdx (via @objectstack/spec)
  • content/docs/permissions/positions.mdx (via @objectstack/spec)
  • content/docs/permissions/rls.mdx (via @objectstack/spec)
  • content/docs/permissions/sharing-rules.mdx (via @objectstack/spec)
  • content/docs/plugins/adding-a-metadata-type.mdx (via @objectstack/spec)
  • content/docs/plugins/development.mdx (via @objectstack/spec)
  • content/docs/plugins/index.mdx (via @objectstack/spec)
  • content/docs/plugins/packages.mdx (via @objectstack/spec)
  • content/docs/protocol/backward-compatibility.mdx (via @objectstack/spec)
  • content/docs/protocol/diagram.mdx (via packages/spec)
  • content/docs/protocol/kernel/config-resolution.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/i18n-standard.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/index.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/lifecycle.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/plugin-spec.mdx (via @objectstack/spec)
  • content/docs/protocol/knowledge.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/query-syntax.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/schema.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/security.mdx (via packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/actions.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/concept.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/layout-dsl.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/record-alert.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/widget-contract.mdx (via @objectstack/spec)
  • content/docs/releases/implementation-status.mdx (via @objectstack/spec)
  • content/docs/releases/index.mdx (via @objectstack/spec)
  • content/docs/releases/v12.mdx (via @objectstack/spec)
  • content/docs/releases/v13.mdx (via @objectstack/spec)
  • content/docs/releases/v16.mdx (via @objectstack/spec)
  • content/docs/releases/v17.mdx (via @objectstack/spec)
  • content/docs/releases/v9.mdx (via @objectstack/spec)
  • content/docs/ui/actions.mdx (via @objectstack/spec)
  • content/docs/ui/create-vs-edit-form.mdx (via @objectstack/spec)
  • content/docs/ui/dashboards.mdx (via @objectstack/spec)
  • content/docs/ui/forms.mdx (via @objectstack/spec)
  • content/docs/ui/index.mdx (via @objectstack/spec)
  • content/docs/ui/public-data-collection.mdx (via @objectstack/spec)
  • content/docs/ui/setup-app.mdx (via @objectstack/spec)
  • content/docs/ui/translations.mdx (via @objectstack/spec)
  • content/docs/ui/views.mdx (via @objectstack/spec)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@xuyushun441-sys
xuyushun441-sys marked this pull request as ready for review August 3, 2026 16:52
@xuyushun441-sys
xuyushun441-sys added this pull request to the merge queue Aug 3, 2026
Merged via the queue into main with commit 32a0874 Aug 3, 2026
24 checks passed
@xuyushun441-sys
xuyushun441-sys deleted the claude/issue-4001-automation-batch9 branch August 3, 2026 17:03
xuyushun441-sys pushed a commit that referenced this pull request Aug 3, 2026
批 9 (#4925) landed the same automation/ ledger section. Both waves deleted
their own rows and decremented the section header by their own count, so git
merged the ROWS cleanly and conflicted only on the header — while the
authorable subtotal one line below, which conflicted with nothing, merged
clean while being wrong on both branches. Header recomputed from the surviving
rows (42 strip of 75, authorable 16 of 42) rather than resolved in favour of
either side; check:strictness-ledger's header arithmetic is the arbiter and
reads 45 open files / 299 strip sites.

os-regen four-step run: merge -> checkout origin/main for every path in
.gitattributes -> wholesale regenerate -> assert siblings survived. 批 9's
three reference pages and #4909's bulk-action page are byte-identical to
origin/main.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ehu85kbvMcrNTUJjwxvLJ9
xuyushun441-sys pushed a commit that referenced this pull request Aug 3, 2026
合并 main 后 `pnpm build` 红:#4925 之外的既有缺陷被这次改动踩到。
`{ handler, effect: 'writes' }` 这个声明形态无法通过 `objectstack build`
—— CLI 把它降级成 `{ handler: 'sweepProjectHealth', effect: 'writes' }`
(lowerCallables 自己的测试就是这么断言的),而 `FlowFunctionEntrySchema`
的三个联合分支只接受:裸 callable、handler 是 callable 的声明、裸字符串
ref,唯独没有「handler 已被降级为字符串的声明」。于是从源码加载全绿
(dev / validate / vitest),只有构建产物这条路失败——正是 #4343 为裸形态
修掉的那个不对称,晚了一个形态。已拆 #4976。

`packages/spec` 本轮零改动,所以 showcase 改用裸函数形态,并在原处留下
不要改回去的理由 + issue 链接。运行时没有损失:`effect` 只有 script 节点
的 `unmeasuredEffect` 一个消费者,job 这条路的 `collectBundleFunctions`
本来就只保留 handler。

守卫相应调整为「functions 条目必须是构建能承载的形态」,并注明 #4976 落地
后应当删除该守卫而不是绕过它。

复核(合并 main 后重跑):`pnpm build` 全仓 71/71 绿,showcase 构建产物
bundle 到 2 个 handler;typecheck / 84 tests / validate 绿;全新库冷启仍是
2 条无关告警,且 `[migration] new datastore attested at creation` 与
`[value-shape] this deployment has verified …— enforced` 均出现。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NrmBxj8rK2uGCnh9aipjwX
xuyushun441-sys pushed a commit that referenced this pull request Aug 3, 2026
Ledger conflict was expected and is the three-way `automation/` header the
dispatch note warned about: 批 9 (#4925) landed on main while this branch was
open, and both sides edit the same section. Resolved by keeping BOTH sides' row
edits and recomputing the header from the merged rows rather than taking a side:

  批 9  removed builtin-node-config (8) / schemaless-node-config (4) /
        io-node-config (2), and rewrote their triage notes
  批 11 removed flow-function (1) / time-relative-trigger (1) / webhook (1),
        and dropped flow.zod.ts 7 → 1

  header  67 → 44 strip of 75   (13+10+1+6+5+5+4, summed from the rows)
  authorable  41 → 18           (etl 7 + state-machine 6 + control-flow 5)

`check:strictness-ledger` arbitrates that arithmetic and passes; the header was
NOT copied from either side.

os-regen four-step ran in full: merge → `git checkout origin/main --` every
`merge=os-regen` path → `pnpm install --frozen-lockfile` + rebuild spec +
`check:generated --fix` (regenerated `content/docs/references/**` only) → assert
BOTH sides survive. Sibling entries verified present after the wholesale
regeneration: 批 9's NotifyConfig / HttpConfig / Script node-config pages and
#4922's `data/SortNode` are all in `authorable-surface.json` beside this
branch's `automation/Webhook:_packageId` / `:protection`.

Merged-tree verification (§10: main touched packages/spec, the same package as
this diff, so the full suite was re-run rather than scoped):
  check:generated 8/8 · all 8 pure audits PASS (incl. strictness-ledger)
  @objectstack/spec 297 files / 7450 tests · tsc --noEmit clean

Part of #4001

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ehu85kbvMcrNTUJjwxvLJ9
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/xl tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants