Skip to content

docs: accept the hook-body write-set static-analysis gap (ADR-0107) - #3716

Merged
os-zhuang merged 2 commits into
mainfrom
claude/hookschema-structured-writes-czvrhp
Jul 27, 2026
Merged

docs: accept the hook-body write-set static-analysis gap (ADR-0107)#3716
os-zhuang merged 2 commits into
mainfrom
claude/hookschema-structured-writes-czvrhp

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

落实 #3700 的短期建议(选项 1):接受 hook body 写入面的静态检查缺口,并把它写进文档 —— 即 #3583 评估文档 §5 D4 的 (a)。选项 2(结构化 writes 声明)按 issue 的定位保留为独立提案,继续在 #3700 讨论,本 PR 不实现它,因此用 Refs 而非 Closes 关联。

改动内容

  • docs/adr/0107-hook-body-write-set-accepted-static-gap.md(新增) — 决策记录:
    • D1 接受缺口并在作者会读到的每个界面标注(ADR-0049 的 trichotomy:不可覆盖的面必须标注,不能默认让作者以为有覆盖);
    • D2 永久不做对 body 源码的启发式静态分析(正则/AST 猜测写入集)—— 部分覆盖会制造「写入已被检查」的假信心,与评估 §7 的立场一致;
    • D3 结构化 writes 声明定位为能力提案(声明 → lint 校验 → 运行时强制,与 capabilities 同形),deferred + evidence-gated,由 Hook body writes are not statically checkable — accept the gap or give HookSchema a structured writes declaration #3700 跟踪;ADR-0078 §4 的注册期诊断维持原判,不在此重新决策;
    • D4 现有的作者侧缓解指引。
    • ADR 里还记录了当前的真实运行时行为(写入未知字段时):validateRecord 跳过未知键 → SQL driver 把未知列透传给数据库、整个操作在运行期报错;schemaless driver(memory/MongoDB)则静默持久化,与成功不可区分。
  • content/docs/automation/hook-bodies.mdx — 新增「Not statically checked: the write set」小节:明确检查边界(condition 读取侧和 capability 面有检查;写入集没有)、运行时后果、以及替代做法(写入集固定时优先用 flow update_record 节点,它的结构化 fields 是可被 lint 检查的)。
  • content/docs/automation/hooks.mdx — Best Practices 增加一条指向上述小节。
  • packages/spec/src/data/hook-body.zod.tsScriptBodySchema TSDoc 声明该盲区(契约自述边界)。仅注释,无行为变化。
  • docs/audits/2026-07-app-metadata-reference-integrity-assessment.md — §5 D4 标记为已决策,并链接落点。

验证

  • pnpm --filter @objectstack/spec test:256 个文件、6688 个用例全部通过。
  • pnpm --filter @objectstack/spec check:docs:250 个生成文件与 spec 同步(TSDoc 注释不影响生成的 references)。
  • 纯文档 + TSDoc 改动,无运行时行为变化;按 AGENTS.md 清单,非 feature 不加 changeset。

Refs #3700, #3583

🤖 Generated with Claude Code

https://claude.ai/code/session_01EsRh53G7SMwFQL57BpFDsx


Generated by Claude Code

Closes out option 1 of #3700 (from the #3583 reference-integrity
assessment, §5 D4): the set of fields a hook body writes lives in an
opaque JS string, so unknown-field writes cannot be statically checked —
and per the assessment's own posture, must be marked rather than guessed
at.

- ADR-0107 records the decision: accept + mark the gap (D1), never
  heuristically analyze body source (D2), and route the structured
  `writes` declaration as a deferred, evidence-gated capability proposal
  tracked in #3700 (D3), with author guidance (D4).
- content/docs/automation/hook-bodies.mdx gains "Not statically checked:
  the write set" — the exact coverage boundary (condition and
  capabilities are checked; writes are not), the runtime failure modes
  (late SQL driver error vs. silent persistence on schemaless drivers),
  and what to do instead.
- hooks.mdx best practices point at that section.
- ScriptBodySchema TSDoc states the blind spot at the contract itself.
- The assessment's open decision D4 is recorded as decided.

No behavior change; documentation and TSDoc only.

Refs #3700

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EsRh53G7SMwFQL57BpFDsx
@vercel

vercel Bot commented Jul 27, 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 Jul 27, 2026 3:56pm

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation protocol:data size/m labels Jul 27, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

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

104 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 packages/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 packages/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/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/kernel/runtime-capabilities.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/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.

The Check Changeset gate requires every PR to add a changeset; an
empty-frontmatter changeset is its sanctioned "this PR releases
nothing" declaration.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EsRh53G7SMwFQL57BpFDsx
@os-zhuang
os-zhuang marked this pull request as ready for review July 27, 2026 16:08
@os-zhuang
os-zhuang merged commit 53d37f1 into main Jul 27, 2026
17 checks passed
@os-zhuang
os-zhuang deleted the claude/hookschema-structured-writes-czvrhp branch July 27, 2026 16:25
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 protocol:data size/m tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants