Skip to content

docs(skills): the objectstack-data skill leads a hook author to the save notice - #30947

Merged
os-zhuang merged 3 commits into
mainfrom
claude/project-thread-q060ym
Nov 6, 2026
Merged

os-zhuang merged 3 commits into
mainfrom
claude/project-thread-q060ym

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Tesla · project thread

Fixes #28819

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:objectstack-data 技能的规则索引里,rules/lifecycle.md 条目补上「保存提示」(ctx.notice)一句;references/data-hooks.md 的沙箱 ctx.* 表与 HookContext 清单各加一行 notice,都指向 rules/lifecycle.md § Save Notice。新增全部用同文件内删除重复叙述来付账,两行 token 棘轮按落地读数下调(6123→6078、10066→10011)。
  • 为什么改:保存提示的教学已在 rules/lifecycle.md,但索引把该页写成只讲数据保留,钩子参考里又没有 notice,写保存钩子的作者从本技能进来找不到它。
  • 风险与回滚:只改技能文本与棘轮上限,不改运行时;若有误,revert 本 PR 即可。
  • 先看:skills/objectstack-data/references/data-hooks.md(新增的 ctx.notice 行、notice? 成员,以及被删的三段)、skills/objectstack-data/SKILL.md 第 45 行与 lifecycle 属性行、scripts/check-skills-token-ratchet.mjs 两行下调。
  • 两分钟验证:node scripts/check-skills-token-ratchet.mjs | grep objectstack-data/,预期 SKILL.md is 6078 tokens (ceiling 6078; headroom 0) 与 data-hooks.md is 10011 tokens (ceiling 10011; headroom 0)。
  • 需要你做的:skills/** 为 Tier H,席位契约复审通过后由你批准合并。

What changes

skills/objectstack-data/SKILL.md — the rule index (L45). The rules/lifecycle.md entry gains one clause: "plus the save notice a hook hands the saver (ctx.notice)". The "distinct from lifecycle hooks below" parenthesis stays, since the page is still the retention page, and now also where the save notice is taught.

skills/objectstack-data/references/data-hooks.md — two rows.

  • Sandbox ctx.* table: a ctx.notice row — (message) => void, tell the saver what this save set in motion, answered as the create/update notice and shown on the save toast, no capability, insert/update only, last call wins, linking rules/lifecycle.md § Save Notice. Every word is read off main: HookContextSchema.notice (packages/spec/src/data/hook.zod.ts, "no capability token", "last call before the write answers wins", "present on every insert/update dispatch", "absent on find and delete"), the body runner's hand-over (packages/runtime/src/sandbox/body-runner.ts, notice: engineCtx.notice) and the VM bridge (packages/runtime/src/sandbox/quickjs-runner.ts, "No capability gate").
  • HookContext listing: notice?: (message: string) => void; // Save notice — rules/lifecycle.md § Save Notice, beside api?, matching the spec's optional member and HookNoticeSetter.
  • Paid by three same-file deletions of restated prose:
    1. In the body section intro, "and the one that was previously undocumented (you had to reverse-engineer @objectstack/runtime to use it)" — history of the page, not a rule; the sentence keeps "the one a metadata-only runtime actually executes".
    2. The blockquote "The former ctx.session.tenantId alias was removed in v16 … (The generic driver-layer execCtx.tenantId / DriverOptions.tenantId isolation knob is a separate axis and is unaffected.)" — its first half is the HookContext listing's own comment on organizationId ("The former tenantId alias was removed in v16"), its second half is the "Two isolation axes" blockquote directly below it.
    3. The paragraph "ctx.user is the ergonomic shortcut for an authenticated caller; it is undefined for system / unauthenticated writes, so read ctx.session?.organizationId when a hook must work regardless of whether a user resolved." — the ctx.user table row and the listing's comment both say "undefined for system / unauthenticated writes", and the code line right above it (ctx.user?.organizationId ?? ctx.session?.organizationId) is the fallback it describes.

scripts/check-skills-token-ratchet.mjs — both rows re-locked DOWN at the landed counts (6123 → 6078, 10066 → 10011), each with a comment naming what paid for what. No ceiling rises.

Changeset: .changeset/28819-save-notice-discoverable.md, '@objectstack/skills': patch, with both declaration lines.

Skill bundle readings (skills/** touched)

before (origin/main 4d56914) after (79305e90, same bytes as 6edbf15a)
skills/objectstack-data/SKILL.md 465 lines · 6087 tokens 465 lines · 6078 tokens
skills/objectstack-data/references/data-hooks.md 973 lines · 10056 tokens 965 lines · 10011 tokens
all 11 SKILL.md in skills/ 4525 lines · 56670 tokens 4525 lines · 56661 tokens

Tokens are the gate's own convention, ceil(utf8 bytes / 4), with the 20-byte version: stamp line unpriced on a SKILL.md.

Tests

Prose only, so no package test and no ablation (the ablation rule excludes docs). The teaching was checked against main's code, not memory:

  • node scripts/check-skills-token-ratchet.mjs --self-test — 97 cases pass, exit 0.
  • node scripts/check-skills-token-ratchet.mjs — both edited rows report headroom 0, exit 0.
  • skills/objectstack-data/evals/ has no runner in this tree (skills/README.md L74: the fixtures are scored by maintainers); the two JSON fixtures are not touched and the ratchet still measures them (1753 / 1749 tokens, not ratcheted).

Acceptance notes

  • The ctx.notice row sits between ctx.crypto and ctx.title, so the table stays in its "gated members, then ungated helpers" order.
  • Not a defect: HookContext.notice is declared optional on the schema (a context built without a live engine parses), so the listing spells it notice?:, like api?:.
  • Out of scope, noted only: the optional-properties table and the rule index both still describe lifecycle twice (row + index entry); that duplication predates this PR and pays for it here, nothing more was cut.

Verification

Derived gates: 64 derived, 63 run green, 1 NOT MEASURED (head 6edbf15)

node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 64 commands at 6edbf15a. Each ran with stdin from /dev/null, its exit code written to disk before any pipe (ran-list: project files skills-seat-2/r2026-11-06/out/28819-gates-ran-6edbf15a.list).

  • 63 exit 0, among them check-skills-token-ratchet (+ --self-test, 97 cases), check:skill-identifier-liveness, check:skill-frame-sync, check:skill-compatibility, check:pm-skill-id-lint, check:doc-authoring, check:role-word, check:nul-bytes, check:changeset-gate-self-tests, check-empty-changeset --base origin/main, check-adr-0087-registration --base origin/main, check-changeset-no-major --base origin/main, check:pm-governed-merges, check:pm-dispatch-gates, @objectstack/spec check:skill-docs and check:skill-refs, @objectstack/lint check:doc-formula-expressions.
  • pnpm check:lean-entry-closure: exit 3 (no packages/objectql/dist) on the first pass; after pnpm --filter '@objectstack/objectql...' build under the verify lock it exits 0 ("Admitted set held exactly (15 packages)"). The ran-list carries the 0.
  • pnpm check:dual-build-cjs-loads: exit 3, PREREQUISITE NOT MET — it loads every published package's dist (89 absent). NOT MEASURED locally; the diff touches no package it loads, and CI's Lint & Repo Gates runs it.

Reconciliation: dispatch-gates --repo objectstack-ai/objectstack --ran printed 64 derived famil(ies) accounted for — 63 run, 1 NOT-MEASURED (1 DERIVED from a recorded exit 3).

Head 79305e90 is 6edbf15a merged with origin/main 33043bd (one i18n commit, no file in common). On the merged head the base-sensitive families re-ran green: check-skills-token-ratchet, check-empty-changeset --base origin/main, check-adr-0087-registration --base origin/main, check-changeset-no-major --base origin/main, check:skill-identifier-liveness, all exit 0; the four changed files and their bytes are identical to 6edbf15a.

Prerequisite builds, both under scripts/pm/os-verify-lock.sh: pnpm --filter '@objectstack/lint...' build (VERDICT command-exit 0, 108 s) and pnpm --filter '@objectstack/objectql...' build (VERDICT command-exit 0, 150 s).

Tier H by path (skills/**). It stays a draft: the seat runs the at-tier contract review, then the maintainer approves and merges.


Generated by Claude Code

…ave notice

The rule index's rules/lifecycle.md entry names the save notice, and
references/data-hooks.md carries a ctx.notice row in the sandbox table and a
notice member in the HookContext listing, each pointing at the Save Notice
section. Growth is paid by deleting restated prose in the same files, and
both token-ratchet rows are re-locked at the landed counts.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L9qibx4SVi1CLmwbLz82b7
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface labels Nov 6, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:skills#2 · os-tesla · session_01L9qibz5RLVEYDFco93jZ7u

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 79305e90579ad3dadca3173c20af3c8be821d357
Local-runs: none
Scope: skills/objectstack-data/SKILL.md, skills/objectstack-data/references/data-hooks.md + packages/spec/src/data/hook.zod.ts, packages/runtime/src/sandbox/body-runner.ts, packages/runtime/src/sandbox/quickjs-runner.ts, packages/objectql/src/hook-notice.ts, skills/objectstack-data/rules/lifecycle.md, scripts/check-skills-token-ratchet.mjs

Inputs read: card #28819 (body, triage 6684772134, claim 6685096576, dev report 6685780581); PR #30947 body, file list (4 files) and the compare/main...79305e90 net diff (2 ahead, 0 behind); the check-runs on 79305e90. The cited code was read at 79305e90, which is main for every file outside the diff.

① Derived judgments

  • ctx.notice row (sandbox table) — right. Name, shape and conditions match HookContextSchema.notice (hook.zod.ts: HookNoticeSetter, one message: string argument returning void, .optional(), "no capability token", "last call before the write answers wins", "present on every insert / update dispatch … absent on find and delete"), the engine's binder (hook-notice.ts: NOTICE_EVENTS = before/afterInsert, before/afterUpdate; delete context.notice on every other event) and the sandbox hand-over (body-runner.ts L1312–1316 notice: engineCtx.notice, hook face only; quickjs-runner.ts L951–973 vm.setProp(ctxObj, 'notice', …), "No capability gate", synchronous). "Shown on the save toast" and "answered as the create/update notice" are what rules/lifecycle.md § Save Notice teaches on main. The row sits after ctx.crypto (last gated member) and before ctx.title (ungated helper): the table's order holds.
  • notice? member (one message: string argument, returns void) in the HookContext listing — right. Optional on the schema (z.unknown().optional() cast to HookNoticeSetter), so notice? beside api? is the spec's own shape; a context parsed without a live engine has neither. The comment points at rules/lifecycle.md § Save Notice, the page that owns the rule.
  • Anchor ../rules/lifecycle.md#save-notice — right. ## Save Notice exists at rules/lifecycle.md L144 on main; Lint · docs & code guards and Lint · repo & tooling gates (skill-refs / skill-docs) are green on this head.
  • SKILL.md L45 index clause — right. The entry now names the save notice and ctx.notice, and L46 still routes to references/data-hooks.md, which now carries the member twice. rules/lifecycle.md L7 on main already says "and, at its end, the save notice a hook hands the saver", so the index describes the page as it is. Verify section untouched (queued skills: three skills say a bare field ref in a predicate "evaluates to null" and silently hides or never fires; main fails loud #30893).
  • SKILL.md lifecycle row trim — right. The dropped clause ("a telemetry/transient/event/audit class must declare a bounding policy or parsing fails") lives in the index entry one screen above ("❗ append-only objects must declare one") and in rules/lifecycle.md § Validation Rules ("rejected at parse time" … "Non-record class with no bounding policy"). The row keeps the bolded requirement and its link.
  • Three data-hooks.md deletions — homes verified at head: (1) the "previously undocumented / reverse-engineer" aside is page history, not a rule, and the sentence keeps "the one a metadata-only runtime actually executes"; (2) the tenantId blockquote: first half is the listing comment at L589 ("The former tenantId alias was removed in v16"), second half is the "Two isolation axes" blockquote at L625–637 ("the generic driver-layer tenantId knob … a separate axis") — see ④ for the two symbol names it loses; (3) the ctx.user paragraph: "undefined for system / unauthenticated writes" is the table row at L360 and the listing comment at L603, and the ?? fallback is the code line at L622 directly above.
  • Token ratchet rows — right, both re-locked DOWN at the measurement. Reproduced by the gate's own audit arithmetic (ceil(utf8 bytes / 4), stamp line unpriced) on the fetched files: SKILL.md 24331 bytes − 20-byte version: "18.3.0" line → 6078 (main 24367 → 6087); data-hooks.md 40042 bytes → 10011 (main 40224 → 10056). Pinned 6123→6078 and 10066→10011, headroom 0 on both; no ceiling rises. Lint · repo & tooling gates (the ratchet's CI home) is green on 79305e90.
  • Accept-set / public surface: none. No schema, runtime or exported type changes; the skill bundle changes text only. The @objectstack/skills package is the only published artifact touched.
  • Check-runs on 79305e90 at write time: every Lint, Type Check, Build, Changeset, Queue Guard, PR-body guard, Dogfood and Test UI family concluded success; Test Core (1/8) and (2/8) still in_progress (3/8 green). Those are package unit-test shards and read no skills/** file; no family that judges the hits files is outstanding.

② Semver level

.changeset/28819-save-notice-discoverable.md — '@objectstack/skills': patch. Right: skill prose and two ratchet constants, no API or accepted-set change. Clause-②: no and Metadata-protocol: none are on both the PR body and the changeset, no (narrowing) arm, so the PR is on the rules face (governed skills/** path) at CONTRACT_REVIEW_TIER. Check Changeset and check-changeset-no-major green.

③ Boundary flags

  • Dev report open_questions: [] — nothing to answer.
  • Deviations (4): mistyped hooks path on a never-pushed first commit, re-committed as 6edbf15 with hooks running; edits in the linked worktree; harness assignee step skipped (seat sets it); worktree kept until landing. All procedural, none reaches the tree.
  • out_of_scope_findings: lifecycle still described in two places in SKILL.md (row + index). Duplication, not a defect, not filed — accepted as noted; the card's own ask was the row clause only.
  • PR body "Acceptance notes": notice? optional is not a defect — agreed, see ①.
  • check:dual-build-cjs-loads NOT MEASURED locally — CI's Lint families are green on this head, which covers it.
  • No escalation needed.

④ Design judgment

skills/objectstack-data/references/data-hooks.md — judged against the card's scenario (an author writing a save hook from this skill) and the spec it teaches on main.

  • Holds. An author reaching the sandbox table or the HookContext listing now finds notice, its exact signature, its three conditions (no capability, insert/update only, last call wins) and the rule page. Each condition was checked against the binder, not the PR body: hook-notice.ts binds on the four insert/update events and deletes the member otherwise; the member itself refuses a non-string; the VM bridge installs it only when the host handed it over.
  • Tried to break it: (a) "insert/update only" vs beforeDelete/afterFind — correct, the member is absent there; (b) handler door — HookContextSchema declares it, so a typed handler reads ctx.notice?.() with no TS2339, unlike ctx.title; the row rightly carries no "per door" caveat; (c) action bodies — body-runner.ts hands it over on the hook face only; the row's "insert/update only" already excludes actions, which have no such dispatch (observation, not a fix: the table's action parenthetical has never listed the hook-only members title/dispatch either); (d) "Capabilities — the complete list" still says "exactly five" tokens and notice adds none — consistent.
  • Should-fix — deletion (2) loses two symbol names. The removed blockquote named execCtx.tenantId / DriverOptions.tenantId; the surviving "Two isolation axes" note at L633 says only "the generic driver-layer tenantId knob". The rule (separate axis, unaffected by the v16 alias removal) has its home; the two identifiers no longer appear anywhere in skills/objectstack-data/. Either add the two symbols to the two-axes note when headroom allows, or record the loss as intended. Not a must-fix: an author searching this skill for the hook-side org value still lands on organizationId and the two-axes rule.

skills/objectstack-data/SKILL.md — judged against the card's reach (SKILL.md L45–46 is the only route from the skill into the save-notice teaching).

  • Holds. L45 now names the save notice with the member spelled ctx.notice, L46 leads to data-hooks.md where the member is listed, and both point back to rules/lifecycle.md § Save Notice. The parenthetical "(distinct from lifecycle hooks below); plus the save notice a hook hands the saver" reads slightly against itself, but it is accurate: the page is the retention page and also where the notice is taught, exactly as its own L7 says.
  • The lifecycle row trim loses no rule the skill does not state elsewhere (index entry + rules/lifecycle.md § Validation Rules).
  • No must-fix.

Cited gate — scripts/check-skills-token-ratchet.mjs (read, not reviewed): both constants equal the head's measured counts; see ①.

  • Should-fix (nit) — the data-hooks.md row comment nets "+95 … (-141)" = −46, while the pinned move from the main count is 10056→10011 = −45 (per-piece ceil rounding). The constant is right; only the comment's arithmetic is off by one.

No must-fix found in either hits file.

Implemented-by: claude/project-thread-q060ym
Reviewed-by: session_01L9qibz5RLVEYDFco93jZ7u

VERDICT: PASS

…xes note

Contract review should-fixes on the save-notice rows: the two-axes note in
references/data-hooks.md now carries execCtx.tenantId / DriverOptions.tenantId,
which the deleted blockquote had named; paid by the session.roles history
clause and two bytes of punctuation in the new rows. The ratchet row comment
states the net move instead of per-piece counts.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L9qibx4SVi1CLmwbLz82b7
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:skills#2 · os-tesla · session_01L9qibz5RLVEYDFco93jZ7u

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 8111c0d57659bcf847eb53bbe78a50a1ae75786e
Local-runs: none
Scope: skills/objectstack-data/SKILL.md, skills/objectstack-data/references/data-hooks.md + packages/spec/src/data/hook.zod.ts, packages/spec/src/kernel/execution-context.zod.ts, packages/spec/src/data/driver.zod.ts, packages/objectql/src/engine-driver-options.ts, scripts/check-skills-token-ratchet.mjs

Delta review on the previous PASS record for 79305e90 (PR comment of 2026-11-06T13:27Z). 8111c0d5 is one commit on 79305e90 (compare: 1 ahead, 0 behind) touching two files, skills/objectstack-data/references/data-hooks.md (+5/−4) and scripts/check-skills-token-ratchet.mjs (+7/−5). SKILL.md and the changeset are byte-identical to the reviewed head. Only what moved is judged here; everything else in the earlier record stands.

① Derived judgments

  • Restored symbols — match main. The two-axes note (L633) now names execCtx.tenantId / DriverOptions.tenantId. ExecutionContext.tenantId is declared at packages/spec/src/kernel/execution-context.zod.ts L135 and read by the engine as execCtx.tenantId (packages/objectql/src/engine-driver-options.ts L428, L497); DriverOptions.tenantId is packages/spec/src/data/driver.zod.ts L53 ("Tenant Isolation identifier"). The spec's own session.organizationId doc (hook.zod.ts L1205–1209) names exactly this pair as "a distinct, configurable axis", which is the sentence the note now carries. The earlier should-fix is closed.
  • Trim 1, ctx.session row (L361): "it was declared but never produced, so every read was undefined" to "(declared, never produced)" — no fact lost. The spec tombstone (hook.zod.ts L1308–1318) says the key was DECLARED and NEVER PRODUCED on the hook path, so both readers "resolved undefined on every real engine path"; "never produced" entails that read result, and the spec itself names the pattern "declared-never-produced" (L1256). What an author needs survives: ctx.session has no role list, session.roles was retired in 17.0.0, and the Common Patterns warning at L849 ("Never gate this on a session claim: ctx.session?.roles?.includes(…)") is untouched.
  • Trim 2, ctx.notice row: "Rules: " prefix dropped — no fact lost. The link text rules/lifecycle.md § Save Notice already names the rules page.
  • Trim 3, notice? listing comment: dash to colon — punctuation only.
  • ctx.notice row — still correct. Signature (one message argument, returns void), "answered as the create/update notice, shown on the save toast", "No capability; insert/update only; last call wins", link to ../rules/lifecycle.md#save-notice: unchanged against HookContextSchema.notice, hook-notice.ts and the sandbox hand-over read for the previous record.
  • Ratchet constant — matches the measurement. data-hooks.md at 8111c0d5 is 40042 bytes, ceil(40042 / 4) = 10011 = ceiling, headroom 0 (966 lines: the blockquote wraps onto one more line, same byte count). SKILL.md unchanged at 24331 bytes, 6078 with the stamp line unpriced. The row comment now reads "main measured 10056; the move is -45" — main is 40224 bytes → 10056, so −45 is exact; the earlier nit is closed. The comment also credits the session.roles clause as a payer, which is what the diff shows.
  • Accept-set / public surface: none moved.

② Semver level

Unchanged: .changeset/28819-save-notice-discoverable.md, '@objectstack/skills': patch, Clause-②: no, Metadata-protocol: none; prose and a comment only. Check Changeset green on 8111c0d5.

③ Boundary flags

No new dev flags, no open questions on the delta commit. Both should-fixes from the 79305e90 record are addressed in the tree, not only in the account.

④ Design judgment

skills/objectstack-data/references/data-hooks.md — judged against the earlier record's two should-fixes and the author scenario (writing a save hook, reading the org, checking isolation axes). The two-axes note now gives an author the two symbols to search for, under the rule that owns them; the three trims pay for it without removing a condition, a version or a warning. The ctx.notice teaching is the same contract as before. No must-fix, no should-fix.

scripts/check-skills-token-ratchet.mjs (cited gate, read not reviewed): constant unchanged at 10011 and equal to the head's count; the comment's arithmetic is now right.

Check-runs on 8111c0d5 at write time: success — Auto Label, Build Core, Check Changeset, Check PR Size, Dogfood Regression Gate, Governed Surface Queue Guard, Lint · ESLint, Lint · repo & tooling gates (the token ratchet's CI home), Lint · scoped · query-options erasure, Lint · scoped · tooling self-tests, Live E2E UI, PR-body guards, Plan Test Core shards, Test UI, Type Check · source gates, filter (16). in_progress — Lint · CI release & engine gates, Lint · PM dispatch-gates, Lint · docs & code guards, Lint · scoped · slot lookup & corpus, Test Core (3 shards), Type Check · consumer gates / debt ledger / workspace (10). None failed. The ratchet gate has concluded green; Lint · docs & code guards (skill-refs / doc guards) is the one still-running family that reads the hits file, on a change that adds no link and no heading. 13 skipped (UI, opt-in and schedule jobs, as on the previous head).

Implemented-by: claude/project-thread-q060ym
Reviewed-by: session_01L9qibz5RLVEYDFco93jZ7u

VERDICT: PASS

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:skills#2 · os-tesla · session_01L9qibz5RLVEYDFco93jZ7u

维护者速读

  • 改了什么:让数据技能里的「保存提示」找得到。SKILL.md 规则索引里 rules/lifecycle.md 一条补一句:它也讲保存提示(不只是数据保留)。references/data-hooks.md 的沙箱 ctx.* 表加 ctx.notice(message) 一行(仅 insert/update,最后一次调用生效,不需要能力授权),HookContext 列表加 notice? 成员,都指向 rules/lifecycle.md#save-notice。另有 changeset。
  • 为什么改:PR docs(skills): objectstack-data rules/lifecycle.md teaches the save notice #28813 已在 rules/lifecycle.md 教了保存提示,但技能索引说那个文件只讲数据保留,钩子参考页也没有 notice,写保存钩子的 AI 找不到它。
  • 风险与回滚:只改技能文字和 changeset,不碰运行时。篇幅靠同文件删除换来(每处的去处在 PR 正文里写明),两行 token 上限都下调到实测:SKILL.md 6123 → 6078,data-hooks.md 10066 → 10011,没有上调。回滚即 revert。
  • 先看:skills/objectstack-data/references/data-hooks.md 新增的 ctx.notice 行和 notice? 成员。
  • 两分钟验证:git grep -n "notice" skills/objectstack-data/references/data-hooks.md skills/objectstack-data/SKILL.md,对照 packages/objectql/src/hook-notice.ts。
  • 需要你做的:改的是 skills/**,属于 Tier H,需要 os-zhuang(或 hotlong)批准后才能合并。契约复审 PASS 6685938271,补改后增量复审 PASS 6686154027。

席位意见:契约复审 PASS,无必改;两条建议修改(删掉的 execCtx.tenantId / DriverOptions.tenantId 两个符号名、ratchet 注释的数字)开发已补上,增量复审无发现。可以批准。

席位核对

ACCEPT · seat domain:skills#2 · head 8111c0d5 · 2026-11-06T13:56Z

  1. Shape: Fixes #28819, draft, base main, 4 files (skills/objectstack-data/SKILL.md rule-index entry, skills/objectstack-data/references/data-hooks.md table row + HookContext member, scripts/check-skills-token-ratchet.mjs two rows down, .changeset/28819-save-notice-discoverable.md '@objectstack/skills': patch); content commit 6edbf15a, a merge of main 33043bd8 (no file in common) and fix commit 8111c0d5.
  2. Ruling: filing gate ② on skills(objectstack-data): the save notice is undiscoverable — the SKILL.md rule index calls rules/lifecycle.md retention-only, and references/data-hooks.md has no ctx.notice row #28819 (open_question of PR docs(skills): objectstack-data rules/lifecycle.md teaches the save notice #28813's dev report); blockers skills: teach the save notice in the objectstack-data lifecycle rule #28253 and skills(objectstack-data): teach an object extension's fieldPatches in the Object Extension Model section, once #28565 applies them #28730 closed completed; triage 6684772134 (p3); Claim 6685096576.
  3. Contract review: PASS 6685938271 at 79305e90 (no must-fix, two should-fixes). Delta PASS 6686154027 at 8111c0d5 (same reviewer, no findings): the "Two isolation axes" note names execCtx.tenantId / DriverOptions.tenantId again (spec execution-context.zod.ts, driver.zod.ts), paid by three trims that lose no fact; the ratchet row comment states the net move 10056 → 10011 (−45). ctx.notice / notice? match main: HookContextSchema.notice optional, typed HookNoticeSetter (message string, returns void); packages/objectql/src/hook-notice.ts binds it on before/after insert and update only; the QuickJS sandbox installs it with no capability gate; the #save-notice anchor resolves in rules/lifecycle.md. All three same-file deletions have homes on the head. Clause-②: no, Metadata-protocol: none.
  4. Gates / check-runs: dev reports 64 derived families, 63 exit 0, dual-build-cjs-loads NOT MEASURED locally (needs every dist; CI runs it), base-sensitive families re-run green on the merged head (report 6685780581, lists skills-seat-2/r2026-11-06/out/28819-*). Ratchet rows re-locked at the measurement, headroom 0: SKILL.md 6078, data-hooks.md 10011. On head 8111c0d5: 42 check-runs, 29 success, 13 skipped, 0 failed; mergeable_state clean. Refreshed os-dev-report 6686486027 (64 derived, 63 exit 0, dual-build-cjs-loads NOT MEASURED, CI green).
  5. Accepted deviations: the PR body is not patched and is stale in three places (the deletion list, the notice? comment punctuation, the head in the readings); this ACCEPT and the delta record carry the head-8111c0d5 facts. The dev's first local commit ran without the pre-commit hook (never pushed) and was redone as 6edbf15a with hooks. Both review should-fixes are closed on this head.
  6. Landing: GOVERNED, Tier H (skills/**). The seat readies the PR and the relay's governed-review leg requests the approvers; no auto-merge is armed by the seat.

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/s tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface

Projects

None yet

2 participants