Skip to content

chore: version packages - #26517

Open
github-actions[bot] wants to merge 1 commit into
mainfrom
changeset-release/main
Open

github-actions[bot] wants to merge 1 commit into
mainfrom
changeset-release/main

Conversation

@github-actions

@github-actions github-actions Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and publish to npm yourself or setup this action to publish automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

The changelog information of each package has been omitted from this message, as the content exceeds the size limit.

@objectstack/cli@18.3.0

@objectstack/client@18.3.0

@objectstack/cloud-connection@18.3.0

@objectstack/connector-mcp@18.3.0

@objectstack/connector-openapi@18.3.0

@objectstack/connector-rest@18.3.0

@objectstack/core@18.3.0

@objectstack/driver-odata@18.3.0

@objectstack/driver-sql@18.3.0

@objectstack/formula@18.3.0

@objectstack/lint@18.3.0

@objectstack/metadata@18.3.0

@objectstack/metadata-core@18.3.0

@objectstack/metadata-protocol@18.3.0

@objectstack/objectql@18.3.0

@objectstack/platform-objects@18.3.0

@objectstack/plugin-approvals@18.3.0

@objectstack/plugin-audit@18.3.0

@objectstack/plugin-auth@18.3.0

@objectstack/plugin-email@18.3.0

@objectstack/plugin-security@18.3.0

@objectstack/plugin-sharing@18.3.0

@objectstack/rest@18.3.0

@objectstack/runtime@18.3.0

@objectstack/service-analytics@18.3.0

@objectstack/service-automation@18.3.0

@objectstack/service-i18n@18.3.0

@objectstack/service-messaging@18.3.0

@objectstack/skills@18.3.0

@objectstack/spec@18.3.0

@objectstack/types@18.3.0

@object-ui/console@18.3.0

@object-ui/cli@18.3.0

@object-ui/components@18.3.0

@object-ui/core@18.3.0

@object-ui/data-objectstack@18.3.0

@object-ui/fields@18.3.0

@object-ui/i18n@18.3.0

@object-ui/layout@18.3.0

@object-ui/plugin-calendar@18.3.0

@object-ui/plugin-dashboard@18.3.0

@object-ui/plugin-detail@18.3.0

@object-ui/plugin-form@18.3.0

@object-ui/plugin-gantt@18.3.0

@object-ui/plugin-grid@18.3.0

@object-ui/plugin-kanban@18.3.0

@object-ui/plugin-list@18.3.0

@object-ui/plugin-map@18.3.0

@object-ui/plugin-timeline@18.3.0

@object-ui/plugin-tree@18.3.0

@object-ui/plugin-view@18.3.0

@object-ui/react@18.3.0

@object-ui/types@18.3.0

@objectstack/hono@18.3.0

@objectstack/account@18.3.0

@objectstack/setup@18.3.0

@objectstack/studio@18.3.0

@objectstack/client-react@18.3.0

@objectstack/connector-slack@18.3.0

create-objectstack@18.3.0

@objectstack/driver-memory@18.3.0

@objectstack/driver-mongodb@18.3.0

@objectstack/driver-sqlite-wasm@18.3.0

@objectstack/driver-turso@18.3.0

@objectstack/mcp@18.3.0

@objectstack/metadata-fs@18.3.0

@objectstack/observability@18.3.0

@objectstack/embedder-openai@18.3.0

@objectstack/knowledge-memory@18.3.0

@objectstack/knowledge-ragflow@18.3.0

@objectstack/organizations@18.3.0

@objectstack/plugin-dev@18.3.0

@objectstack/plugin-hono-server@18.3.0

@objectstack/plugin-pinyin-search@18.3.0

@objectstack/plugin-webhooks@18.3.0

@objectstack/service-cache@18.3.0

@objectstack/service-cluster@18.3.0

@objectstack/service-cluster-redis@18.3.0

@objectstack/service-datasource@18.3.0

@objectstack/service-job@18.3.0

@objectstack/service-knowledge@18.3.0

@objectstack/service-mailbox@18.3.0

@objectstack/service-package@18.3.0

@objectstack/service-print@18.3.0

@objectstack/service-queue@18.3.0

@objectstack/service-realtime@18.3.0

@objectstack/service-settings@18.3.0

@objectstack/service-sms@18.3.0

@objectstack/service-storage@18.3.0

@objectstack/trigger-api@18.3.0

@objectstack/trigger-record-change@18.3.0

@objectstack/trigger-schedule@18.3.0

@objectstack/verify@18.3.0

@object-ui/auth@18.3.0

@object-ui/collaboration@18.3.0

@object-ui/create-plugin@18.3.0

@object-ui/mobile@18.3.0

@object-ui/permissions@18.3.0

@object-ui/plugin-charts@18.3.0

@object-ui/plugin-chatbot@18.3.0

@object-ui/plugin-designer@18.3.0

@object-ui/plugin-editor@18.3.0

@object-ui/plugin-markdown@18.3.0

@object-ui/plugin-report@18.3.0

@object-ui/providers@18.3.0

@object-ui/react-runtime@18.3.0

@objectstack/connector-imap@18.3.0

@objectstack/console@18.3.0

@objectstack/sdui-parser@18.3.0

@object-ui/app-shell@18.3.0

@objectstack/example-crm@4.0.103

@objectstack/example-multi-package@0.0.10

@objectstack/example-showcase@0.3.25

@objectstack/example-todo@4.0.103

@objectstack/example-embed-objectql@0.0.43

@objectstack/connector-app-github@0.1.1

@objectstack/connector-app-stripe@0.1.1

@objectstack/dogfood@0.0.51

@objectstack/downstream-contract@0.0.49

@objectstack/http-conformance@0.1.11

@github-actions
github-actions Bot force-pushed the changeset-release/main branch 2 times, most recently from 2ff177c to c7bf16c Compare October 27, 2026 18:11
@github-actions
github-actions Bot force-pushed the changeset-release/main branch from c7bf16c to cc06e79 Compare October 28, 2026 00:20
@github-actions
github-actions Bot force-pushed the changeset-release/main branch from cc06e79 to e99a182 Compare October 28, 2026 06:16
@github-actions
github-actions Bot force-pushed the changeset-release/main branch from e99a182 to 603d78c Compare October 28, 2026 12:12
@github-actions
github-actions Bot force-pushed the changeset-release/main branch 2 times, most recently from 5b303cc to 68b6101 Compare October 29, 2026 00:20
@github-actions
github-actions Bot force-pushed the changeset-release/main branch from 68b6101 to 2840914 Compare October 29, 2026 06:14
@github-actions
github-actions Bot force-pushed the changeset-release/main branch from 2840914 to 0dee0ad Compare October 29, 2026 12:13
@objectstack-fleet

Copy link
Copy Markdown
Contributor

triage#1 · os-sales · session_01L6bhgV4fMGJHSdSdx3u9mK

Contract-review-claim: session_01L6bhgV4fMGJHSdSdx3u9mK · head 0dee0ad · 2026-10-29T15:21Z


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor

triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

Contract-review-claim: session_01AavokzJ5DndAwitDXvKy4U · head 0dfbc1c2ac0ac483c28ec373e4350a05a9fc4cdd · 2026-11-01T10:18Z

Taken under references/contract-review.md (b): this head has waited a full triage round with no record, claim or hand-off on it. Face rules, so the review runs at CONTRACT_REVIEW_TIER. The previous PASS (6523675066) names an earlier head. ⛔ A review only: triage never merges, readies or dispatches this PR.


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor

triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 0dfbc1c2ac0ac483c28ec373e4350a05a9fc4cdd
Local-runs: none
Scope: skills/objectstack-ai/SKILL.md, skills/objectstack-api/SKILL.md, skills/objectstack-automation/SKILL.md, skills/objectstack-data/SKILL.md, skills/objectstack-formula/SKILL.md, skills/objectstack-i18n/SKILL.md, skills/objectstack-platform/SKILL.md, skills/objectstack-query/SKILL.md, skills/objectstack-ui/SKILL.md, skills/objectstack-upgrade/SKILL.md, skills/objectui/SKILL.md + scripts/check-skill-compatibility-version.mjs, scripts/check-skills-token-ratchet.mjs (CEILINGS, isEvalFixture, pricedTokens, generatorOwning), scripts/pm/check-governed-merges.mjs (spec-skill-refs register row), package.json (root version script), .changeset/config.json, .github/workflows/release.yml (version-pr, Validate the post-version tree), .github/workflows/publish-smoke.yml, .github/workflows/pr-automation.yml (Check Changeset), packages/skills/scripts/sync-catalog.mjs, packages/skills/CHANGELOG.md, packages/spec/package.json, packages/skills/package.json, packages/core/package.json, packages/formula/package.json, packages/services/service-automation/src/builtin/connector-nodes.ts, packages/services/service-automation/src/builtin/crud-nodes.ts (resolveNodeFilter), packages/services/service-automation/src/engine.ts (NodeFailureClass), packages/services/service-automation/src/flow-registration-checks.ts, packages/lint/src/validate-expressions.ts, packages/connectors/connector-rest/src/connector-rest-plugin.ts, packages/connectors/connector-openapi/src/connector-openapi-plugin.ts, packages/connectors/connector-openapi/src/openapi-provider.ts, packages/connectors/connector-mcp/src/mcp-provider.ts, packages/services/service-automation/src/oauth2-grant/, packages/spec/src/system/translation.zod.ts, packages/spec/src/system/i18n-resolver.ts, packages/spec/src/ui/page.zod.ts, packages/spec/src/ui/view.zod.ts (NavigationModeSchema, size, drawerWidth), packages/spec/src/data/object.zod.ts, packages/spec/src/data/field.zod.ts (relatedList*, percentDisplay, lookupAutofill, scale), packages/spec/src/ui/action.zod.ts (pressed), packages/spec/src/ui/component.zod.ts (polarity), ui/packages/plugin-detail/src/synth/recordPageColumns.ts, ui/packages/plugin-detail/src/RecordPageColumns.tsx, packages/services/service-datasource/src/datasource-env-credential.ts, skills/objectstack-ui/rules/record-page.md, skills/objectstack-ui/evals/record-page.json, skills/objectstack-automation/references/integration-recipes.md (main's carry-over, read)

Delta record. The previous record on this PR is comment 6523675066 (PASS, head 0c9d8e0b, parent 5448585d). The Changesets action's 6-hourly version-pr run (Release run 41279688431, schedule, 06:09:47Z to 06:14:25Z on 2026-11-01) regenerated changeset-release/main on main 071bda62 (06:07Z). The new head is that one commit, chore: version packages (06:14:13Z, author and committer github-actions[bot]), whose parent is 071bda62. This time the PR API's base.sha is 071bda62 too, so the API base and the merge base agree. The net diff the files endpoint returns (eleven pages, 1070 files: 814 changesets removed, 121 package.json, 120 CHANGELOG.md of which 3 are new files, 11 SKILL.md, 4 docs/docker image-tag files) agrees with git diff 071bda62 0dfbc1c2 file for file (1070 files, 44963 insertions, 13273 deletions). The run's Version PR maintenance job closed success with every step green: Verify Changesets "fixed" group covers every public package, Render the post-version tree, Validate the post-version tree, Stage the post-version changesets for the read rehearsal, Rehearse the version-PR changeset read on the post-version tree, Assert the read rehearsal found nothing left to version, Restore the pre-version tree, Create or update the "chore: version packages" PR.

This move is NOT pure regeneration, so this is a full delta review, not a carried record. The PR's own contribution is the same as before: eleven one-line stamps. But main moved 264 commits between the two bases (5448585d to 071bda62), and that carry-over changed 22 files under skills/, three of them hits files: skills/objectstack-automation/SKILL.md (38 lines), skills/objectstack-i18n/SKILL.md (4 lines) and skills/objectstack-ui/SKILL.md (28 lines). The pricer scripts/check-skills-token-ratchet.mjs also moved. Every item the move touches is judged afresh below. Between the two heads, these cited files are the SAME blob: check-skill-compatibility-version.mjs (b333603), sync-catalog.mjs (44ed00a), release.yml (b197935), publish-smoke.yml (5e32fe6), pr-automation.yml (da8e4b2), .changeset/config.json (6a18140), root package.json (4e9d2ee), sync-template-versions.mjs, sync-docs-image-tags.mjs, sync-release-index-currency.mjs, check-docs-image-tag.mjs. The four docs/docker files differ from the previous head by one line only: the release date in content/docs/releases/index.mdx moves from 2026-10-30 to 2026-11-01. What the move leaves alone stands as judged in record 6523675066, naming it.

① Derived judgments

  • Accept set: unchanged — right (re-judged). The eleven hits hunks are one line each, metadata.version "18.2.0" to "18.3.0", double-quoted as the writer spells them. Against the head's base 071bda62, each SKILL.md differs by that line alone (git diff 071bda62 0dfbc1c2 -- skills/: 11 files, 11 insertions, 11 deletions). No rule text, no schema, no example moves in the PR's own diff.
  • Main's carry-over into three hits files, read and placed. (a) skills/objectstack-automation/SKILL.md: two main commits. docs(skills,automation): a connector_action input is judged against the action's inputSchema before dispatch, refused as VALIDATION_ERROR #28170 (91fa06df8d, declared late by changeset 28041-skills-connector-input-judged, @objectstack/skills: patch, Clause-②: no) rewrites the connector_action row: registerFlow and os validate refuse a single-brace token at connectorConfig.input.KEY; once evaluated, the input is judged against the action's inputSchema (required, type, properties, items) before dispatch; a breach fails the step VALIDATION_ERROR, fault-routable, nothing sent; os validate does not judge the inputSchema fit yet. The same commit pays for the row by deleting restatements in the file: the record_change row's triggerType parenthetical, "e.g. approval" and "(from plugin-approvals)", the null-operand bullet's "(not fault-routable)", the script item's "notify delivers, connector_action reaches a vendor, a function computes", the requires paragraph's "the surface just never runs", the example's "bare CEL" comment, and "never an http node holding a credential". skills(automation): teach oauth2 and app-credential as a recipe once a built-in provider takes the grant (S2 of #26702) #28299 (3eb6dfcf9e, changeset 28299-automation-skill-oauth-recipe, patch, Clause-②: no) drops "OAuth, request signing" from the loader-gap list. (b) skills/objectstack-i18n/SKILL.md: skills: teach action.pressed in the objectstack-ui actions rule #28243 (3b45d4a4c0, changeset 28243-skills-ui-i18n-teach-six-keys, patch, Clause-②: no) adds submitBehavior.title / submitBehavior.message under _views.{view_name} (a form whose submitBehavior is kind: 'thank-you'; the other kinds carry none) and submitText under _actions.{action_name} (the param dialog's button verb, only under an action that declares params). (c) skills/objectstack-ui/SKILL.md: skills(objectstack-ui) + docs: teach the record page as it is now — object roles produce the page, six slotted slots, kind: full as the escape hatch, drawer default with page by declaration, the column tiers and the reader's own toggles — and stop naming tabs, modal / split / popover #27059 (efb1620c63, PR docs(skills): objectstack-ui teaches the record page as the Console ships it #28498, changeset 27059-skills-record-page-rules, patch, Clause-②: no) replaces the two related-list paragraphs (the "Read side" and "Related-list layout" blocks) with a two-line pointer at rules/record-page.md, adds that file to the Detailed Rules list, and rewrites the blueprint's "Record pages" row: synthesized from the object's declarations, src/pages/*.page.ts only to override a slotted slot or for a kind: 'full' layout. The other eight SKILL.md files are byte-identical between the two heads. All three are judged against the code they cite in ④.
  • Main's other skills-tree carry-over, read and placed. Nineteen more files under skills/ moved between the bases. Hand-authored: objectstack-automation/references/integration-recipes.md and evals/integrations-declared.json (recipe 6 for oauth2 / app-credential, the signed kind: changesets 28299, 28226); objectstack-data/rules/datasources.md (the code-defined datasource credential route OS_DATASOURCE_NAME_PASSWORD behind OS_DATASOURCE_ENV_CREDENTIALS: 28209), rules/field-types.md (28051, 28203, 28256, 28489, 8345), evals/hooks-security-seeds-datasources.json (28435); objectstack-platform/references/operations.md (27331, the Marketplace handbook link); objectstack-ui/rules/actions.md, rules/list-views.md (28243, 28476), rules/dashboards.md (28243, 28051, 8345), rules/navigation.md, rules/pages.md (27059, 27375), rules/record-page.md (new, 27059), evals/README.md, evals/record-page.json (new), evals/views-apps-actions-pages.json. Generator-owned: the four references/_index.md files (ai, automation, data, ui), written by gen:skill-refs and verified by check:skill-refs; check-governed-merges.mjs register row spec-skill-refs owns them, so they need no changeset and are outside the priced population (generatorOwning). Sixteen changesets new in the move name @objectstack/skills: 27059, 27191 (minor, with @objectstack/spec), 27331, 27375, 28041, 28051, 28203, 28209, 28226, 28243, 28256, 28299, 28435, 28476, 28489, 8345. The @objectstack/skills CHANGELOG at the head carries 54 entries under 18.3.0 against 38 at the previous head, and 54 is the number of changesets at the base that name the package. No carried-in hand-authored skills edit lacks a changeset naming the catalog package.
  • The pricer moved, and the arithmetic holds. scripts/check-skills-token-ratchet.mjs differs between the heads in its CEILINGS table and comments alone (d6d3573 to b52b8b3); isEvalFixture, pricedTokens and generatorOwning are unchanged. Six rows move: objectstack-automation/SKILL.md 6457 to 6450 (lowered, card skills(automation): teach oauth2 and app-credential as a recipe once a built-in provider takes the grant (S2 of #26702) #28299); objectstack-ui/SKILL.md 3851 to 3544 (lowered, skills(objectstack-ui) + docs: teach the record page as it is now — object roles produce the page, six slotted slots, kind: full as the escape hatch, drawer default with page by declaration, the column tiers and the reader's own toggles — and stop naming tabs, modal / split / popover #27059); objectstack-ui/rules/navigation.md 2273 to 2196 (lowered); objectstack-ui/rules/pages.md 5692 to 5669 (lowered); objectstack-ui/rules/record-page.md 996 (new, pinned at 3981 bytes); objectstack-automation/references/integration-recipes.md 2236 to 2488 (raised on the standing path, two same-file restatement cuts named, pinned at 9949 bytes). The table holds 57 rows and zero on an evals/ path. Measured at the head with the pricer's own rule (ceil(utf8 bytes / 4), a stamped SKILL.md less its 20-byte stamp line): automation SKILL.md 25819 bytes, 25799 priced = 6450 (ceiling 6450, headroom 0); ui SKILL.md 14194, 14174 priced = 3544 (3544, 0); i18n SKILL.md 22604, 22584 priced = 5646 (6333, 687); integration-recipes.md 9949 = 2488 (0); record-page.md 3981 = 996 (0); navigation.md 8784 = 2196 (0); pages.md 22673 = 5669 (0); datasources.md 3640 = 910 (911); field-types.md 12828 = 3207 (3207); operations.md 12494 = 3124 (3125); actions.md 9024 = 2256 (2259); dashboards.md 24992 = 6248 (6262); list-views.md 12438 = 3110 (3129). The six eval files are measured, not ratcheted. Every lowered ceiling equals the landed measurement; nothing is over; no raise exceeds its stated byte count.
  • Public surface: the catalog's self-declared version moves to 18.3.0 — right, and derived (re-judged). scripts/check-skill-compatibility-version.mjs is the same blob as at the previous head and derives metadata.version from CATALOG_VERSION_PACKAGE = '@objectstack/spec'; packages/spec/package.json, packages/skills/package.json, packages/core/package.json and packages/formula/package.json all read 18.3.0 at the head (18.2.0 at the base). sync-catalog.mjs is unchanged and ships skills/** verbatim into @objectstack/skills@18.3.0. The root version script is unchanged; its last step, node scripts/check-skill-compatibility-version.mjs --fix, is what wrote the eleven lines. Stamp, anchor and catalog package agree.
  • The fixed group: unchanged — right. .changeset/config.json is the same blob (109 members, three ignore patterns). The version-pr job's covers-every-public-package step passed on this tree.
  • compatibility: lines: unchanged — right. Spec, core and formula are all at major 18, so every 18.x pin stands; the upgrade skill's EXEMPT entry still matches its live compatibility: text, which nothing in the move touched.
  • Coverage: complete (re-checked on the new head). git ls-tree on 0dfbc1c2 shows eleven skill directories beside skills/README.md and eleven SKILL.md files, all at depth three, none deeper; git grep 18.2.0 over skills/ at the head returns nothing; the only version: lines under skills/*/SKILL.md are the eleven stamps plus the version: '1.0.0' inside the platform skill's code block.
  • Gate verdicts on the head. Check-runs on 0dfbc1c2: zero, the documented shape for a GITHUB_TOKEN push (release.yml lines 306 to 326 and publish-smoke.yml say so; both blobs unchanged). The 17 check-suites are 12 github-actions suites at action_required and five queued third-party apps, none carrying a run; the 12 workflow runs on this head (CI, Lint & Type Check, Governed Surface Guard, PR-Body Guards, Spec Liveness Check, Docs Drift Check, Check Links, Validate Dependencies, PR Automation, Scaffold E2E, Pack Smoke, Upgrade Harness) all read action_required, which is "did not run", not red. The gate the release commit passes is the version-pr job's post-version validation, which refuses the force-push on red, so the head's existence is that gate's green; run 41279688431's steps all read success. The commit status publish-smoke / packed-tarballs: 33 smokes have reported to this head. Sixteen closed success ("Fresh install of the release candidate: auth + CRUD green"), the first 41282714707 at 07:06:04Z and the latest 41295448653 at 10:00:33Z; sixteen were cancelled before a verdict (superseded by a newer smoke, by cancel-in-progress); none failed; one, 41297511014, is in_progress since 10:27:52Z. The combined status reads pending because the newest status is the in-flight run's. Unlike the previous head, this head has already been smoked green many times.
  • Outside the hits (lane seat's ACCEPT, named here only). 110 package.json hunks are the fixed group's "version": "18.3.0" line alone (109 members plus the odata driver); ten private workspaces outside the group take dependency-driven patch bumps (4.0.103 twice, 0.0.10, 0.3.25, 0.0.43, 0.0.51, 0.0.49, 0.1.11, and two new since the previous head: @objectstack/connector-app-github and @objectstack/connector-app-stripe 0.1.0 to 0.1.1, private, each gaining a first CHANGELOG.md of "Updated dependencies" lines); packages/create-objectstack/src/templates/blank/package.json moves its nine @objectstack/* ranges to 18.3.0 through sync-template-versions.mjs. The third new CHANGELOG is packages/drivers/driver-odata/CHANGELOG.md, the package's first section. The four non-package files are the ghcr.io/objectstack-ai/objectstack:18.3.0 image tags, OS_CLI_VERSION=18.3.0, @objectstack/cli@18.3.0 and the "current series: 18.3.0, released 2026-11-01" line. Derived, not reviewed.

② Semver level

  • The PR carries no changeset of its own and no skip-changeset label: it is the consuming side. .changeset/ at the head holds README.md and config.json only; 814 changeset files are removed, which is every .md beside the README at the head's base 071bda62 (815 minus 1): the 584 the previous head consumed plus the 230 main added between 5448585d and 071bda62, none dropped. Two carried changesets were edited in place on main (27626-record-open-requests, 28019-derived-measure-fixed-currency: body text, levels unchanged). Tallied from the removed files' frontmatter at 071bda62: 320 minor entries, 1240 patch entries, 0 major (665 files patch-only, 131 minor-only, 18 mixed). The highest level across the fixed group is minor, so the group moves 18.2.0 to 18.3.0 — the level the diff publishes.
  • Breaking-marked subjects, checked for a hidden major. 134 of the 814 changesets open with a ! subject (102 at the previous head, 32 new in the move). Every one declares patch or minor (76 patch-only, 49 minor-only, 9 mixed) and every one of the 814 carries its own Clause-②: line; none declares major. Refusals added at doors and keys retired with their prescriptions, as their changesets say; 18.3.0 is right. The levels themselves were judged on the PRs that introduced them.
  • Fifty-four changesets name @objectstack/skills: 48 patch and 6 minor. The six minors are 25769-ownership-queue, 27016-queues-reserved-membership-key, 27053-page-slots-tabs-retired, 27069-related-lists-order, 27462-count-rollup-without-field (all five already at the previous base, so the previous record's "one carried minor" undercounted them) and 27191-home-amount-pointer (new in the move). Each is a spec change shipping with its teaching, and minor is the group's level anyway; the 16 new skills changesets in ① are all patch and Clause-②: no except 27191. None raises the group's level above minor.
  • The Check Changeset gate (pr-automation.yml) exempts exactly this head: branch changeset-release/main and author github-actions[bot], pinned together. Same blob as before.
  • Clause-②: line: none on the PR body — the body is the Changesets action's template. The face is the rules face, decided by paths (skills/** sits in the governed register), so the tier is not read off a Clause-②: line.

③ Boundary flags

  • Author login. The PR's author is github-actions[bot], not objectstack-fleet[bot]: changesets/action opens and force-pushes the PR with the default GITHUB_TOKEN, and that is the login pr-automation.yml pins for the release-PR exemption. Expected identity; no escalation.
  • Zero check-runs. Structural (see ①); the gate reading is the version-pr validation that produced the head plus the publish-smoke commit status.
  • Commit status — the previous record's open flag is answered. Record 6523675066 waited for a success smoke on its head. This head has sixteen, the first at 07:06:04Z. The combined status still reads pending because smoke 41297511014 is in flight at the time of this record; a later main push will keep restarting it. The seat should read the combined status at merge time; a failure would be a new input this record did not see and asks for a fresh record. The standing green verdicts on this exact sha are already in the status list.
  • Main's Release runs around this head: all green. The previous record flagged a red Cancel waiting publish prompts step on a Release run of 2026-10-30. Every Release run between 05:32Z and 06:55Z on 2026-11-01 (18 runs, 17 push and the one schedule run that produced this head) closed success. Nothing red to place.
  • Staleness — 38 commits, and one hits file body moved on main after this head. GitHub main (28ef35e0e3, 10:05:46Z) is 38 commits ahead of the head's parent 071bda62, adding 34 changesets (848 pending on main against the 814 this head consumes) and touching four skills/** paths: skills/objectstack-platform/SKILL.md, skills/objectstack-platform/references/operations.md and evals/config-plugins-ops.json (skills/docs: teach the one effective read of a .custom declared override (N-10's owed Skills-docs follow-up; the first slice of N-30) #28509, 8de519ff07, the one effective read of a .customize package) and skills/objectstack-automation/references/integration-recipes.md (docs(skills): the automation mcp recipe teaches the providerConfig.toolsSnapshot pin #28597, 28f2e99b8a, the providerConfig.toolsSnapshot pin, changeset 28582-skills-mcp-tools-snapshot). None contradicts what this head ships: toolsSnapshot itself lands after this head (27401-mcp-tools-snapshot), so the catalog at this head teaches no key the spec at this head lacks. A merge now leaves those 34 to the next train; release-integrity warns of each. If 18.3.0 is meant to carry them, dispatch Release with refresh_version_pr before merging; the next 6-hourly tick does the same, and each regeneration re-runs the smoke from scratch and asks for a fresh record. Among the 38 are eleven more ! subjects (8a12a17a, bca27ad3, a2e75562, cd065d36, d94dd3a6, 20dcc075, 7449e479, f3d84b33, 672bda0c, 819b1017, f3f7b629); their levels are the next train's record to judge.
  • Base sha on the PR object. base.sha equals the head's parent (071bda62) at the time of this record. No divergence to place.
  • Main's carry-over does not break the stamp. The three SKILL.md body edits sit in tables and body paragraphs, outside the frontmatter the stamp reader parses; the version-pr validation ran check:skill-compatibility and check:skills-token-ratchet on exactly this tree and passed. Every carried-in priced file is at or under its ceiling (arithmetic in ①), the lowered rows sit at the landed measurement, the one raise is pinned at its stated byte count with its cuts named, and the catalog package's CHANGELOG declares every carried-in hand-authored skills edit.
  • One spec-prose observation for the seat, not a defect of this head. packages/spec/src/data/field.zod.ts line 1927 still describes relatedList: true as "a side card in the record's related column (the shared Related tab on the tabbed page)" and 'primary' as "inside the Details tab on the tabbed page", while rules/record-page.md (and the Console's recordPageColumns.ts / RecordPageColumns.tsx at the head) teach a right column of panels and a tab row of Overview, 动态 and one tab per panel. The skill teaches the Console as shipped; the .describe() text is main's, not this PR's, and was quoted as current by the previous record. A one-line spec prose card, if the seat wants the two to agree.
  • Auto-merge. Not armed (auto_merge: null), not draft, no labels. Nothing to disarm.
  • No dev flags and no open_questions exist: bot-authored PR, no card.

④ Design judgment

Judged for every hits file against the code it cites and the scenario it is accepted against: the stamp's reader (check:skill-compatibility, which requires metadata.version to equal @objectstack/spec's workspace version), its pricer (check-skills-token-ratchet, which excludes the one stamp line from the priced bytes and prices no eval fixture or generator-owned file), and its consumer (sync-catalog.mjs, which ships the file verbatim in @objectstack/skills@18.3.0). Reader and consumer are the same blobs as at 0c9d8e0b; the pricer's CEILINGS table moved, read above.

  • skills/objectstack-ai/SKILL.md — stamp "18.3.0"; pin @objectstack/spec 18.x stands against spec 18.3.0. One line changed against the base; byte-identical to the previous head (its references/_index.md is generator-owned). Holds.
  • skills/objectstack-api/SKILL.md — same shape. Holds.
  • skills/objectstack-automation/SKILL.md — stamp "18.3.0", one line changed against the base; one table row, one gap line and seven trims moved against the previous head, main's (docs(skills,automation): a connector_action input is judged against the action's inputSchema before dispatch, refused as VALIDATION_ERROR #28170, skills(automation): teach oauth2 and app-credential as a recipe once a built-in provider takes the grant (S2 of #26702) #28299). Against the engine at the head, connector-nodes.ts lines 126 to 150: resolveValueSlotMap(engine, cfg.input, variables, 'input', context) evaluates the map, then judgeConnectorInput(findConnectorActionInputSchema(engine, cfg.connectorId, cfg.actionId), input) judges the EVALUATED input before handler(input, handlerCtx) is called; a verdict returns success: false, code: 'VALIDATION_ERROR' with "Nothing was sent", and the comment classes it "a runtime failure, not a guard: the input can come from run data, so a fault edge may handle it" — exactly the row's "fails the step VALIDATION_ERROR (fault-routable), nothing sent". Against the authoring doors: flow-registration-checks.ts lines 596 to 604 hand the node to flowNodeValueTemplateRefusals so a single-brace token at connectorConfig.input is refused at registerFlow with its block named (automation: registration does not judge a connector_action node's connectorConfig.input value slot, because the spec expression ledger cannot address a sibling block of config #27968), and validate-expressions.ts lines 2782 to 2800 reach the same slot through resolveFlowNodeExpressions in os validate; packages/lint/src has no reference to inputSchema, so "os validate does not judge the inputSchema fit yet" is true. Against the gap line: connector-rest-plugin.ts, connector-openapi-plugin.ts and connector-mcp-plugin.ts all register with { credentialHandle: true }; openapi-provider.ts lines 238 to 285 and mcp-provider.ts lines 289 to 351 ask ctx.credentialHandle for a grant-bearing instance (oauth2, app-credential, ADR-0143 D4), and service-automation/src/oauth2-grant/ (authorization.ts, app-credential.ts, grant-handle.ts) runs the grant; signed is a declared auth kind (aliyun-acs3-hmac-sha256, ADR-0143 D2.3). So OAuth and request signing are served, and striking them from "a document the loader cannot take yet" is a correction. The seven trims: each deleted clause either survives in the same file or states nothing the engine contradicts. In particular the dropped "(not fault-routable)" on the null-operand bullet is still taught two screens up, in the fault-routing table at line 140 ("Does NOT route (fatal either way): filter operand that evaluated to null"), and the engine agrees: engine.ts NodeFailureClass names "a filter operand evaluated to nothing (Flow node filters silently blank date macros: the template engine consumes {…} before the query engine sees it #3810)" a guard failure, "Not routable — it stays fatal whether or not a fault edge exists", and crud-nodes.ts resolveNodeFilter refuses it. The http row still carries "never a credential there", so the deleted "never an http node holding a credential" is a restatement cut. The file prices at exactly its 6450 ceiling. Holds.
  • skills/objectstack-data/SKILL.md — stamp "18.3.0", one line changed against the base, byte-identical to the previous head; the carried-in edits are in sibling files. Read: rules/datasources.md teaches the env credential route, and datasource-env-credential.ts declares DATASOURCE_ENV_CREDENTIALS_SWITCH = 'OS_DATASOURCE_ENV_CREDENTIALS' with the OS_DATASOURCE_NAME_PASSWORD pattern, while cli/src/utils/datasource-env-credentials-default.ts is the host default the rule names; rules/field-types.md teaches percentDisplay (field.zod.ts line 1597, bar / plain), lookupAutofill (line 2092), the percent storage scale (the scale description: a fraction unless max is above 1, then whole points) and homeAmount.rateDate (ADR-0144 D5, field, rateDate, rateField all required). Holds.
  • skills/objectstack-formula/SKILL.md — stamp "18.3.0"; pins @objectstack/spec 18.x and @objectstack/formula 18.x stand against spec and formula 18.3.0; byte-identical to the previous head. Holds.
  • skills/objectstack-i18n/SKILL.md — stamp "18.3.0", one line changed against the base; two table rows moved against the previous head, main's (skills: teach action.pressed in the objectstack-ui actions rule #28243). Against the spec at the head: translation.zod.ts line 224 declares submitText with "Translated label of the submit button in the action's param dialog (the action must declare params)", and i18n-resolver.ts lines 1587 to 1589 look it up only when action.params is a non-empty array — the row's "only under an action that declares params". translation.zod.ts lines 282 to 297 declare submitBehaviorTranslationSchema with title and message overlaying the thank-you panel, line 336 places it at objects.OBJECT._views.VIEW.submitBehavior.title / .message, and i18n-resolver.ts translateFormSubmitBehavior (line 1333) returns the behavior unchanged unless kind === 'thank-you' and translates authored copy only — the row's "only the copy the form authors is translated, and the other kinds carry none". The file prices at 5646 under a 6333 ceiling. Holds.
  • skills/objectstack-platform/SKILL.md — stamp "18.3.0"; pins @objectstack/spec 18.x and @objectstack/core 18.x stand against spec and core 18.3.0; byte-identical to the previous head (its references/operations.md gains the Marketplace handbook link, which content/docs/deployment/meta.json lists). Holds.
  • skills/objectstack-query/SKILL.md — same shape as ai. Holds.
  • skills/objectstack-ui/SKILL.md — stamp "18.3.0", one line changed against the base; two paragraphs replaced by a pointer, one link added and one blueprint row rewritten against the previous head, main's (skills(objectstack-ui) + docs: teach the record page as it is now — object roles produce the page, six slotted slots, kind: full as the escape hatch, drawer default with page by declaration, the column tiers and the reader's own toggles — and stop naming tabs, modal / split / popover #27059). The pointer's target rules/record-page.md exists at the head (3981 bytes, ratchet row 996 pinned at that count) and is the file the two deleted paragraphs' teaching moved to, so the delegation holds. Against the spec: the blueprint row's "override a slotted slot or kind: 'full'" matches page.zod.ts (kind defaults to 'full' at line 1220; slotted renders its slots, line 1769; page.slots.tabs was removed in 18.3.0 and related / relatedLists are refused as slot names, lines 1287 to 1321; the slot aliases at line 2115 resolve onto discussion, details, alerts, actions, highlights). The record-page rules it points at, checked against the code: object.zod.ts nameField 3375, highlightFields 3416, relatedLists 3459, stageField 3483 (kind open / won / lost, false suppresses), editMode 3501 (modal | page); field.zod.ts relatedList 1927 ('primary' a body table after the first field section, the default for a master_detail with inlineEdit, row order from the child's isDefault list view), relatedListTitle 1929, relatedListColumns 1952, relatedListFilter 1993 (AND-composed, the count honours it); view.zod.ts NavigationModeSchema (drawer, page, new_window, none; modal, split, popover retired by spec(+ui): navigation.mode keeps page | drawer | new_window | none — modal, split and popover are retired; the default becomes drawer in the schema and in the console (no field-count guess); list-page recordAction drops modal; the console's split pane becomes a per-user preference read #26677 with their prescription), size auto to full at 2924, drawerWidth deprecated at 5165; the Console's recordPageColumns.ts lines 19 to 23 (760 px: details beside the right column; 1120 px: three field columns; below 760: one column) and RecordPageColumns.tsx line 352 (the tab row: Overview, 动态, the panels) and lines 63 to 70 (?related=). Against the new eval record-page.json: case 1 ("put the tasks first on the lead page") is relatedList: 'primary' on task.lead, no page file; case 2 (contracts open as a full page; reps want records beside the list) is navigation: { mode: 'page' } and the beside-the-list ask is the reader's own Display choice, as step 6 says. The file prices at exactly its 3544 ceiling, the ratchet's ordinary direction (lowered to the measurement). Holds.
  • skills/objectstack-upgrade/SKILL.md — stamp "18.3.0"; no pin, exempt by the at the TARGET major rationale, which the live compatibility: text still carries. Stamped anyway, as the exemption covers the pin and not the stamp. Holds.
  • skills/objectui/SKILL.md — stamp "18.3.0"; pin @objectstack/spec 18.x stands; byte-identical to the previous head, and no objectui/** sibling moved in this interval. Holds.

Attempts to break it on this head: a skill directory without a SKILL.md (none — eleven directories, eleven files); a nested or extra SKILL.md the one-level walk would miss (none under skills/); a stale 18.2.0 anywhere under skills/ (none); a pin naming a package at a major other than 18 (none); a single-quoted or bare stamp (all double-quoted); a body byte moved beside the stamp in the PR's own diff (none — each file differs from 071bda62 by the one line); a body byte moved by main that the catalog ships without a changeset (none — the three SKILL.md edits and the fifteen hand-authored sibling files are declared by sixteen @objectstack/skills changesets whose CHANGELOG entries the head carries, and the four _index.md files are generator-owned); a carried-in priced file over its ceiling, a lowered ceiling above the landed measurement, or a raise without named cuts (none — all at or under, the four lowered rows and the new row at exactly their measurements, the one raise pinned at 9949 bytes with two cuts named); a CEILINGS row left on an eval path (none — 57 rows, zero under evals/); a SKILL.md sentence that teaches a shape the spec or engine at the head refuses, or a key it no longer has (none — the connector_action row matches connector-nodes.ts and the two authoring doors, the gap line matches the three providers' credentialHandle, the two i18n rows match translation.zod.ts and the resolver, the ui pointer and blueprint row match page.zod.ts); a trim that deleted a true caution with no surviving home (none — the one candidate, "(not fault-routable)", is still taught in the fault-routing table at line 140 and the engine still enforces it); a major hidden behind a ! subject that would have made the right stamp 19.0.0 (none — all 134 declare patch or minor, each with a Clause-②: line); a fixed-group member left out of the version pass (none — 110 18.3.0 lines for 109 members plus the odata driver, and the covers-every-public-package step passed); a reader or consumer that moved under the stamp (none — both blobs unchanged); a failure smoke on this sha (none — sixteen success, sixteen cancelled, one in flight).

Must-fix: none. Should-fix: none on the hits files; the in-flight smoke, the 34-changeset staleness and the field.zod.ts prose observation in ③ are the seat's calls on timing and on a spec card, not defects of this head.

Implemented-by: changeset-release/main
Reviewed-by: session_01AavokzJ5DndAwitDXvKy4U

VERDICT: PASS


Generated by Claude Code

@github-actions
github-actions Bot force-pushed the changeset-release/main branch from 0dfbc1c to 936de78 Compare November 1, 2026 12:12
@objectstack-fleet

Copy link
Copy Markdown
Contributor

triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

Contract-review-claim: session_01AavokzJ5DndAwitDXvKy4U · head 936de78964c0ab0783fec534a66481ae151837d9 · 2026-11-01T12:53Z

The head moved past the PASS 6556828324 on 0dfbc1c2. Under references/contract-review.md, the delta re-review stays with that record's reviewer, this seat. Face rules, so it runs at CONTRACT_REVIEW_TIER. ⛔ A review only: triage never merges, readies or dispatches this PR.


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor

triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 936de78964c0ab0783fec534a66481ae151837d9
Local-runs: none
Scope: skills/objectstack-ai/SKILL.md, skills/objectstack-api/SKILL.md, skills/objectstack-automation/SKILL.md, skills/objectstack-data/SKILL.md, skills/objectstack-formula/SKILL.md, skills/objectstack-i18n/SKILL.md, skills/objectstack-platform/SKILL.md, skills/objectstack-query/SKILL.md, skills/objectstack-ui/SKILL.md, skills/objectstack-upgrade/SKILL.md, skills/objectui/SKILL.md + scripts/check-skill-compatibility-version.mjs, scripts/check-skills-token-ratchet.mjs (CEILINGS, isEvalFixture, pricedTokens, generatorOwning), scripts/pm/check-governed-merges.mjs, package.json (root version script), .changeset/config.json, .github/workflows/release.yml (version-pr, Validate the post-version tree), .github/workflows/lint.yml (the ratchet and check:skill-compatibility steps), .github/workflows/publish-smoke.yml, .github/workflows/pr-automation.yml (Check Changeset), packages/skills/scripts/sync-catalog.mjs, packages/skills/CHANGELOG.md, packages/spec/package.json, packages/skills/package.json, packages/core/package.json, packages/formula/package.json, packages/runtime/package.json, packages/spec/src/kernel/customization-package.ts (customizationPackageId, customizationDependencyRange, OVERRIDE_TYPE_CLASSIFICATION, isOverridableMetadataType), packages/spec/src/kernel/metadata-plugin.zod.ts (DEFAULT_METADATA_TYPE_REGISTRY, allowEnvironmentOverlay), packages/metadata-protocol/src/served-override.ts (isServedOverrideRowOf), packages/metadata-protocol/src/protocol-served-overrides.ts, packages/metadata-protocol/src/protocol.ts (servedOverlayRowCandidates, the env-wide list narrowing, the orphan arm, isOverlayAllowed), packages/metadata-protocol/src/sys-metadata-repository.ts (OVERLAY_ALLOWED_TYPES, envWritableMetadataTypes), packages/runtime/src/domains/packages.ts (the export's per-package layer), packages/objectql/src/protocol-custom-override-effective-read.test.ts, packages/rest/src/public-form-withdrawal-effective-read.test.ts, packages/cli/src/commands/migrate/ (--allow-destructive), skills/objectstack-platform/references/operations.md, skills/objectstack-platform/references/bootstrap.md, skills/objectstack-platform/references/plugin-development.md, skills/objectstack-platform/evals/config-plugins-ops.json, skills/objectstack-data/references/seeds.md, skills/objectstack-data/rules/naming.md, skills/objectstack-automation/references/integration-recipes.md (main's carry-over, read), packages/connectors/connector-mcp/src/mcp-provider.ts, packages/connectors/connector-mcp/src/tool-snapshot.ts, packages/spec/src/data/field.zod.ts (relatedList, for ③)

Delta record. The previous record on this PR is comment 6556828324 (PASS, head 0dfbc1c2, parent 071bda62). The Changesets action's 6-hourly version-pr run (Release run 41305001838, schedule, 12:08:00Z on 2026-11-01) regenerated changeset-release/main on main dd6349ec (11:58Z). The new head is that one commit, chore: version packages (12:12:31Z, author and committer github-actions[bot]), whose parent is dd6349ec. The PR object's base.sha is dd6349ec too, so the API base and the merge base agree. The files endpoint reports 1113 files; git diff dd6349ec 936de789 names 1113 files, file for file. The run's Version PR maintenance job (124843493717) closed success with every step green: Verify Changesets "fixed" group covers every public package, Render the post-version tree, Validate the post-version tree, Stage the post-version changesets for the read rehearsal, Rehearse the version-PR changeset read on the post-version tree, Assert the read rehearsal found nothing left to version, Restore the pre-version tree, Create or update the "chore: version packages" PR.

This move is NOT pure regeneration. unexplainedPathsBetween (the reader regenCarry runs, with origin/main as base) names two paths that lie on no prose face, carry no merge=os-regen attribute and are in the PR's own delta at a head: packages/runtime/package.json and skills/objectstack-platform/SKILL.md. Both moved because main moved under a file the PR stamps, not because the PR wrote anything new, but the reader cannot tell that apart and neither should this record: a hits file's body moved, so this is a full delta review with no Regen-provenance: line. Main moved 49 commits between the two bases (071bda62 to dd6349ec), adding 43 changesets and editing one (25921-collaboration-zero-consumer-exports, body text). Between the two heads 548 files moved; under skills/ four: skills/objectstack-platform/SKILL.md (34 lines), skills/objectstack-platform/references/operations.md (9), skills/objectstack-platform/evals/config-plugins-ops.json (10) and skills/objectstack-automation/references/integration-recipes.md (78). The pricer scripts/check-skills-token-ratchet.mjs moved in two CEILINGS rows. The other ten hits files are byte-identical between the two heads. The PR's own delta against its base is the same as before: git diff dd6349ec 936de789 -- skills/ is 11 files, 11 insertions, 11 deletions. These cited files are the same blob at both heads: check-skill-compatibility-version.mjs (b333603), sync-catalog.mjs (44ed00a), release.yml (b197935), publish-smoke.yml (5e32fe6), pr-automation.yml (da8e4b2), .changeset/config.json (6a18140), root package.json (4e9d2ee), check-governed-merges.mjs (c8fc32a). What the move leaves alone stands as judged in record 6556828324, naming it.

① Derived judgments

  • Accept set: unchanged — right (re-judged). The eleven hits hunks are one line each, metadata.version "18.2.0" to "18.3.0", double-quoted as the writer spells them. Against the base dd6349ec, each SKILL.md differs by that line alone. No rule text, no schema, no example moves in the PR's own diff.
  • Main's carry-over into one hits file, read and placed. skills/objectstack-platform/SKILL.md moved by one main commit, 8de519ff07 (PR docs(skills,docs): objectstack-platform and the metadata-lifecycle page teach the one effective read of a .custom declared override (ADR-0146 D8) #28586, card skills/docs: teach the one effective read of a .custom declared override (N-10's owed Skills-docs follow-up; the first slice of N-30) #28509, changeset 28509-custom-override-read-teaching, @objectstack/skills: patch, Clause-②: no). It adds one paragraph under Manifest Reference, "Customizing an installed package (ADR-0146)": a base hotcrm is customized in its paired writable package hotcrm.custom, which depends on it; a same-named item there with overrides: { package: 'hotcrm', basedOn: '3.2.0' } replaces the base's document whole; the read honours it only from the pair (the row's package_id), today only for a view, dashboard, report, email_template or translation (page, app, dataset, doc, book, mapping, flow and action wait for their doors), never judges basedOn, ignores any other package's declaration; then the read naming no package, the read naming hotcrm, the layered read and both lists serve it; the env-wide list holds one item per name one code package ships, a dependent's staying under its own ?package=; a package-unbound Setup row still wins over the base's until D11; an undeclared pair row or a dependent's row is an orphan in the layered read's overlay with effective the base's; an override may narrow a public form's anonymous intake, never re-open one any honoured body withdrew; GET /packages/hotcrm.custom/export carries it with overrides, the base's export unchanged. It pays for the paragraph in the same file: "Never set tableName, and never add a sys_metadata object to a runtime manifest" moves into the Object naming paragraph; the "Runtime rule of thumb" table (three rows) and the config-generation sentence (short snake_case names, no tableName, no sys_metadata) are deleted; the seed paragraph loses "object is derived … never hand-write a raw data: [{ object: … }] literal"; the CLI cheat sheet code block (eight commands) is deleted; two doubled --- rules become one each. references/operations.md takes the apply rule the cheat sheet carried into its os migrate row ("apply loosens only, --allow-destructive for drops/tightenings") and trims its gates paragraph; evals/config-plugins-ops.json gains case 10 (replace HotCRM's crm_account_grid from hotcrm.custom with overrides:; must not answer with a PUT /meta/view/...). All of it is judged against the code in ④.
  • Main's other skills-tree carry-over, read and placed. skills/objectstack-automation/references/integration-recipes.md moved by 28f2e99b8a (PR docs(skills): the automation mcp recipe teaches the providerConfig.toolsSnapshot pin #28597, changeset 28582-skills-mcp-tools-snapshot, patch, Clause-②: no). Recipe 2 gains the toolsSnapshot paragraph: a sha256 per tool name; a pinned name include leaves out is refused at boot; digests from computeMcpToolsSnapshot(tools) or a 64-hex placeholder then the served digest from the degraded reason; a pinned tool served differently degrades CONNECTOR_UPSTREAM_CHANGED; a pinned tool no longer listed takes the credential path (stored credential rejected) when the instance's credential reached the server, else CONNECTOR_UPSTREAM_CHANGED. Paid for by cuts with a surviving home: the connectorConfig.input bullet shortens to a pointer at SKILL.md's connector_action row; the webhook bullet shortens to a pointer at the api trigger's Signature bullet; the "Not yet — WeChat Pay" section folds into the signed clause of the auth bullet; the OAuth recipe drops the GET reads status / DELETE revokes sentence and the "organization admins by default" aside; six inline code comments and the defaultHeaders example go. Read against the head: mcp-provider.ts lines 433 to 440 refuse a toolsSnapshot name that include leaves out as a configuration fault at boot; lines 583 to 600 compare every pinned tool on its own (compareToolsSnapshot), and a missing pinned tool with credentialSent throws pinnedToolsHiddenError (the credential path, like the include miss at lines 545 to 568 which marks the stored credential rejected), otherwise toolsSnapshotDriftError, a ConnectorUpstreamChangedError; tool-snapshot.ts line 73 exports computeMcpToolsSnapshot. The paragraph matches the engine. Outside the hits; read, not judged.
  • The pricer moved, and the arithmetic holds. scripts/check-skills-token-ratchet.mjs differs between the heads (b52b8b3 to b31e701) in two CEILINGS rows only: skills/objectstack-platform/SKILL.md 6014 to 6012 and skills/objectstack-platform/references/operations.md 3125 to 3119, both lowered (card skills/docs: teach the one effective read of a .custom declared override (N-10's owed Skills-docs follow-up; the first slice of N-30) #28509). isEvalFixture, pricedTokens and generatorOwning are unchanged. The table holds 57 rows and zero on an evals/ path. Measured at the head with the pricer's own rule (ceil(utf8 bytes / 4), a stamped SKILL.md less its 20-byte stamp line): platform SKILL.md 24065 bytes, 24045 priced = 6012 (ceiling 6012, headroom 0); operations.md 12475 = 3119 (3119, 0); integration-recipes.md 9926 = 2482 (2488, 6: the file shrank 23 bytes under the raised row the previous record read, and the row was not lowered to meet it; lowering is the ratchet's encouraged direction, not a gate, and the gate prints the headroom); automation SKILL.md 25819, 25799 priced = 6450 (6450, 0); ui SKILL.md 14194, 14174 priced = 3544 (3544, 0); i18n SKILL.md 22604, 22584 priced = 5646 (6333, 687); bootstrap.md 5398 = 1350 (1351); plugin-development.md 12546 = 3137 (3137); plugin-hooks.md 9650 = 2413 (2628); plugin-lifecycle.md 7099 = 1775 (2408); service-registry.md 7015 = 1754 (2331). Every row is at or under its ceiling; both lowered rows sit at the landed measurement. One comment drifted: the arithmetic line directly above the platform row still reads == ceil(24055 / 4) (6014) while the row reads 6012 and the file prices 24045 bytes, and no comment records the lowering. Comment only, main's, outside the hits.
  • Public surface: the catalog's self-declared version moves to 18.3.0 — right, and derived (re-judged). check-skill-compatibility-version.mjs is the same blob and derives metadata.version from CATALOG_VERSION_PACKAGE = '@objectstack/spec'; packages/spec/package.json, packages/skills/package.json, packages/core/package.json and packages/formula/package.json all read 18.3.0 at the head. sync-catalog.mjs is unchanged and ships skills/** verbatim into @objectstack/skills@18.3.0. The root version script is unchanged; its last step wrote the eleven lines.
  • packages/runtime/package.json, the other path the regeneration test named. Against the base it differs by the one "version": "18.3.0" line. Between the heads it gains "@objectstack/lint": "workspace:*" in dependencies, which is main's 6e11a929e4 (feat(runtime)!: the permission-set clone door lands "new similar" in a writable target package, by default the source package's .custom (#28563) #28636) carried over under the stamp; the PR wrote nothing there. Derived, not reviewed.
  • The fixed group: unchanged — right. .changeset/config.json is the same blob (109 members, three ignore patterns). 109 "version": "18.3.0" lines against the base at this head, 109 at the previous head against its base. The covers-every-public-package step passed on this tree.
  • compatibility: lines: unchanged — right. Spec, core and formula are at major 18; every 18.x pin stands; the upgrade skill's EXEMPT text is unchanged.
  • Coverage: complete (re-checked on the new head). git ls-tree on 936de789 shows eleven skill directories and eleven SKILL.md files at depth three; git grep 18.2.0 over skills/ returns nothing; the only version: lines under skills/*/SKILL.md are the eleven stamps plus version: '1.0.0' inside the platform skill's manifest code block (line 116).
  • Gate verdicts on the head. Check-runs on 936de789: zero, the GITHUB_TOKEN shape release.yml lines 306 to 326 describe (blob unchanged). 17 check-suites: 12 github-actions at action_required with zero runs, five third-party apps queued; the 12 pull_request workflow runs (CI, Lint & Type Check, Governed Surface Guard, PR-Body Guards, Spec Liveness Check, Docs Drift Check, Check Links, Validate Dependencies, PR Automation, Scaffold E2E, Pack Smoke, Upgrade Harness) read action_required, which is "did not run". The gate the release commit passes is the version-pr job's Validate the post-version tree, which runs check:docs-image-tag, check:docs-image-tag-sync, check:template-version-sync, check:release-index-currency-sync, check:skill-compatibility, check:nul-bytes, check:release-notes, check:release-page-status, check-release-section-coverage.mjs, check:published-readme-links, the create-objectstack tests and the spec's check:template-manifests, protocol-version.test.ts, check:spec-changes and check:upgrade-guide on the rendered tree, and refuses the push on red; all green in run 41305001838. The skills token ratchet is not in that list (the previous record said it was; corrected here): it runs in lint.yml (check-skills-token-ratchet.mjs --self-test then the check, with check:skill-refs and check:skill-compatibility) on main, and main's Lint & Type Check run 41304260274 on dd6349ec closed success at 11:58:37Z. The priced bytes of every skills/** file are identical between dd6349ec and this head (the stamp line is not priced), so that verdict is this tree's. Commit status publish-smoke / packed-tarballs: ten statuses from five smoke runs on this sha. Two closed success ("Fresh install of the release candidate: auth + CRUD green"): 41307279455 at 12:47:06Z and 41308229910 at 12:50:11Z. Three were cancelled before a verdict (41305390478, 41305501347, 41306407319, superseded by cancel-in-progress). None failed; none in flight; the combined status reads success.
  • Outside the hits (lane seat's ACCEPT, named here only). 109 package.json hunks are the fixed group's version line alone; private workspaces outside the group take dependency-driven patch bumps (4.0.103 twice, 0.0.10, 0.3.25, 0.0.43, 0.0.51, 0.0.49, 0.1.11, and the two connector apps 0.1.1); packages/create-objectstack/src/templates/blank/package.json moves its @objectstack/* ranges to 18.3.0. The four docs/docker files carry the ghcr.io/objectstack-ai/objectstack:18.3.0 image tags, OS_CLI_VERSION=18.3.0 and @objectstack/cli@18.3.0. 857 changesets removed, 120 CHANGELOGs rewritten. Derived, not reviewed.

② Semver level

  • The PR carries no changeset of its own and no skip-changeset label: it is the consuming side. .changeset/ at the head holds README.md and config.json only; 857 changeset files are removed, which is every .md beside the README at the base dd6349ec (859 entries minus the two kept): the 814 the previous head consumed plus the 43 main added between 071bda62 and dd6349ec, none dropped. Tallied from the removed files' frontmatter: 1289 patch entries, 332 minor entries, 0 major (701 files patch-only, 135 minor-only, 21 mixed). The highest level across the fixed group is minor, so the group moves 18.2.0 to 18.3.0, the level the diff publishes.
  • Breaking-marked subjects, checked for a hidden major. 154 of the 857 changesets open with a ! subject (134 at the previous head, 20 new in the move, among them the eleven the previous record listed and dd6349ec, f23e0512, d6e09673, d2c48740, 6e11a929). Every one declares patch or minor (92 patch-only, 52 minor-only, 10 mixed); none declares major. Every one of the 857 carries a Clause-②: line the fleet reader reads: 614 no, 242 yes, and one yes (narrowing) in backticks (25922-unpublish-app-shell, @object-ui/app-shell: patch, already at the previous base; readClause2Line reads it declared, arm narrowing; what narrows is the npm registry, the package going private: true, not a published accept set). Refusals added at doors and keys retired with their prescriptions, as their changesets say; 18.3.0 is right. The levels themselves were judged on the PRs that introduced them.
  • Fifty-six changesets name @objectstack/skills: 48 patch, 6 minor, 2 mixed with patch elsewhere. The two new in the move, 28509-custom-override-read-teaching and 28582-skills-mcp-tools-snapshot, are both patch and Clause-②: no. The eight above patch (25769-ownership-queue, 27016-queues-reserved-membership-key, 27053-page-slots-tabs-retired, 27069-related-lists-order, 27159-object-form-split-retired, 27191-home-amount-pointer, 27347-object-metric-polarity, 27462-count-rollup-without-field) were all at the previous base; each is a spec change shipping with its teaching, and minor is the group's level anyway. The @objectstack/skills CHANGELOG at the head carries 56 entries under 18.3.0 against 54 at the previous head, and the two new entries are 8de519f and 28f2e99, the two commits whose skills edits ① places. Every carried-in hand-authored skills edit is declared by a changeset naming the catalog package.
  • The Check Changeset gate (pr-automation.yml) exempts exactly this head: branch changeset-release/main and author github-actions[bot], pinned together. Same blob as before.
  • Clause-②: line: none on the PR body; the body is the Changesets action's template. The face is the rules face, decided by paths (skills/** sits in the governed register), so the tier is not read off a Clause-②: line.

③ Boundary flags

  • Author login. The PR's author is github-actions[bot], not objectstack-fleet[bot]: changesets/action opens and force-pushes the PR with the default GITHUB_TOKEN, the login pr-automation.yml pins for the release-PR exemption. Expected identity; no escalation.
  • Zero check-runs. Structural (①); the gate reading is the version-pr validation that produced the head, main's Lint & Type Check on the same skills bytes, and the publish-smoke commit status.
  • Carried item 1, the commit status: resolved. Record 6556828324 left the combined status pending behind an in-flight smoke. On this head the combined status reads success, two smokes closed green on this exact sha, none failed and none is in flight at the time of this record. A later main push restarts the smoke against the release candidate; the seat reads the combined status at merge time, and a failure would be a new input this record did not see.
  • Carried item 2, staleness against main: resolved for the 38 it named, and five new. The previous record flagged main 38 commits ahead with 34 changesets and four skills/** paths (skills/docs: teach the one effective read of a .custom declared override (N-10's owed Skills-docs follow-up; the first slice of N-30) #28509's three platform files and docs(skills): the automation mcp recipe teaches the providerConfig.toolsSnapshot pin #28597's integration-recipes.md). This head is the regeneration that consumed them: the base moved 49 commits, 43 changesets, and all four paths are in this head, read in ① and ④. GitHub main is now e4ec4f22 (12:37:46Z), five commits ahead of dd6349ec, with three new changesets: 28289-create-user-required-field-mark (@object-ui/core, @object-ui/app-shell patch, Clause-②: yes (widening)), 28508-me-permissions-has-any-queue (plugin-sharing, plugin-hono-server patch, yes) and 28560-field-patch-slot (@objectstack/spec: minor, yes (widening), the fieldPatches slot, "not applied yet"). None opens with !; none touches skills/**; the catalog at this head teaches no fieldPatches, which lands after it, so it teaches no key the spec at this head lacks. A merge now leaves those three to the next train; release-integrity warns of each. If 18.3.0 is meant to carry them, dispatch Release with refresh_version_pr before merging; the next 6-hourly tick does the same, and each regeneration asks for a fresh record.
  • Carried item 3, the relatedList prose note: not resolved, and not this PR's. packages/spec/src/data/field.zod.ts line 1927 is byte-identical at this head and on main e4ec4f22: relatedList: true is still described as "a side card in the record's related column (the shared Related tab on the tabbed page)" while rules/record-page.md and the Console teach a right column of panels and a tab row. Still a one-line spec prose card for the seat, if wanted; no sentence of the catalog at this head moved on it.
  • Main's Release runs around this head: all green. The schedule run 41305001838 that produced this head and every push Release run after it (41305392289 at 12:12Z, 41306298775 at 12:23Z, 41307169244 at 12:34Z, 41308131534 at 12:47Z, 41308655347 at 12:54Z on e4ec4f22) closed success.
  • Base sha on the PR object. base.sha equals the head's parent (dd6349ec) at the time of this record. No divergence to place.
  • Main's carry-over does not break the stamp. The platform SKILL.md edits are body paragraphs, a table and a code block, outside the frontmatter the stamp reader parses; check:skill-compatibility passed in the version-pr validation on exactly this tree. Every carried-in priced file is at or under its ceiling (arithmetic in ①), both lowered rows sit at the landed measurement, and the catalog package's CHANGELOG declares both carried-in hand-authored skills edits.
  • Two observations for the seat, neither a defect of this head. (a) The ratchet's arithmetic comment above the platform row reads ceil(24055 / 4) against a row of 6012 and a file of 24045 priced bytes (①); a one-line comment card on main. (b) integration-recipes.md sits 6 tokens under its raised row after docs(skills): the automation mcp recipe teaches the providerConfig.toolsSnapshot pin #28597 shrank it; lowering the row to 2482 is the ratchet's ordinary direction, open to any later PR that touches the file.
  • Auto-merge. Not armed (auto_merge: null), not draft, no labels. Nothing to disarm.
  • No dev flags and no open_questions exist: bot-authored PR, no card.

④ Design judgment

Judged for every hits file against the code it cites and the scenario it is accepted against: the stamp's reader (check:skill-compatibility, which requires metadata.version to equal @objectstack/spec's workspace version), its pricer (check-skills-token-ratchet, which excludes the one stamp line from the priced bytes and prices no eval fixture or generator-owned file), and its consumer (sync-catalog.mjs, which ships the file verbatim in @objectstack/skills@18.3.0). Reader and consumer are the same blobs as at 0dfbc1c2; the pricer's CEILINGS table moved in two rows, read above. In this delta only one hits file's body moved; the other ten are judged on the stamp alone and on nothing having widened the face.

  • skills/objectstack-ai/SKILL.md — stamp "18.3.0"; pin @objectstack/spec 18.x stands against spec 18.3.0; byte-identical to the previous head. Holds.
  • skills/objectstack-api/SKILL.md — same shape. Holds.
  • skills/objectstack-automation/SKILL.md — stamp "18.3.0"; byte-identical to the previous head (its connector_action row, which docs(skills): the automation mcp recipe teaches the providerConfig.toolsSnapshot pin #28597's integration-recipes.md now points at, is unchanged and was judged against connector-nodes.ts in record 6556828324); prices at exactly its 6450 ceiling. Holds.
  • skills/objectstack-data/SKILL.md — stamp "18.3.0"; byte-identical to the previous head; its references/seeds.md line 50 ("object | derived | Auto-set from objectDef.name — never write manually") is the surviving home of the sentence the platform skill deleted, and rules/naming.md carries snake_case. Holds.
  • skills/objectstack-formula/SKILL.md — stamp "18.3.0"; pins @objectstack/spec 18.x and @objectstack/formula 18.x stand; byte-identical. Holds.
  • skills/objectstack-i18n/SKILL.md — stamp "18.3.0"; byte-identical to the previous head; prices 5646 under 6333. Holds.
  • skills/objectstack-platform/SKILL.md — stamp "18.3.0", one line changed against the base; one paragraph added, one sentence moved, a table, a sentence, a seed clause and a code block deleted against the previous head, main's (docs(skills,docs): objectstack-platform and the metadata-lifecycle page teach the one effective read of a .custom declared override (ADR-0146 D8) #28586). The new paragraph, clause by clause against the head. "Paired writable package hotcrm.custom, which depends on it": customization-package.ts customizationPackageId appends the .custom suffix to the base id (lines 94 to 102) and customizationDependencyRange (lines 183 to 207) is the range the pair declares on its base in manifest.dependencies. "A same-named item there with overrides: { package, basedOn } replaces the base's document whole": served-override.ts header, "serves that one document over X's", and servedOverlayRowCandidates (protocol.ts lines 2860 to 2872) puts the pair's declaring row FIRST, ahead of the package's own row and the package-less row. "Honoured only from the pair (the row's package_id)": isServedOverrideRowOf tests isCustomizationPairOf(row.package_id, base) and refuses a body stamp (the _packageId: 'hotcrm.custom' row in its table answers false). "Today only for a view, dashboard, report, email_template or translation; page, app, dataset, doc, book, mapping, flow and action wait for their doors": OVERRIDE_TYPE_CLASSIFICATION lists all thirteen as overridable (customization-package.ts lines 319 to 339), and the predicate asks only isOverridableMetadataType; what narrows it to five is that an override is a stored row, and a stored environment row of a packaged type exists only where DEFAULT_METADATA_TYPE_REGISTRY sets allowEnvironmentOverlay: true (metadata-plugin.zod.ts: view 935, dashboard 937, report 943, translation 1155, email_template 1156, the only five among 44 rows), read through OVERLAY_ALLOWED_TYPES (sys-metadata-repository.ts 408) and isOverlayAllowed (protocol.ts 15786); flow and action are also declined ahead of the predicate (declinesStoredRow, N-11). The five the skill names are those five, and the eight it says wait are the other eight overridable types. "Never judges basedOn": served-override.ts "overrides.basedOn is recorded and never judged (ADR-0146 D2)"; protocol-served-overrides.ts copies it as recorded. "Ignores any other package's declaration": the partner.ext row in the predicate's table answers false; the effective-read test pins "a declaration from a package that is NOT X's pair is ignored (ruling A, docs(adr): ADR-0146 amendment — only the paired <base>.custom declares an override; a dependent package adds under its own names (ruled A, withdraws rider 3) #28390)". "No ?package, ?package=hotcrm, the layered read and both lists serve it": the five reads the served-override.ts header lists and the test's AGREEMENT case, under X's _packageId (test lines 313, 318), which is what eval case 10 asserts. "The env-wide list holds one item per name one code package ships (a dependent's stays under its own ?package=)": protocol.ts lines 10360 to 10395, the servedOverride && !packageId narrowing, "a dependent package's same-named row … is dropped here … still served under its own address". "A package-unbound Setup row still wins over the base's until D11": protocol.ts lines 2870 to 2872, verbatim. "An undeclared pair row or a dependent's row is an orphan in the layered read's overlay, effective = the base's": the test's ORPHANS case and the orphan arm at protocol.ts 12094; the candidate comment at 2829 ("an undeclared row of the pair is that package's own item, never the base's"). "May narrow a public form's anonymous intake, never re-open one any honoured body withdrew": public-form-withdrawal-effective-read.test.ts header, "the base's declared .custom override is the form served, and an override that withdraws the form closes it; an override cannot re-open a form the base's own document withdraws". "GET /packages/hotcrm.custom/export carries it with overrides; the base's is unchanged": packages.ts lines 3224 to 3229, the export reads the per-package layer, "the base's export carries the base unchanged, and its .custom pair's export carries the overriding item with its overrides block". Every clause holds. The deletions: the moved tableName / sys_metadata sentence lands in the Object naming paragraph (line 130), so the rule keeps its home; the three-row table restated the paragraph above it (local dev and runtime read source or artifact, never the business database; the control-plane row survives at references/plugin-development.md lines 305 to 314); the deleted config-generation sentence's tableName and sys_metadata halves moved, and its snake_case half is taught by objectstack-data (SKILL.md, rules/naming.md), the skill that owns object naming; the seed object clause survives in objectstack-data/references/seeds.md line 50, where the paragraph already sends the reader; every cheat-sheet command survives in references/operations.md (os dev --ui line 12, os compile 23, os validate 37, PORT=8080 os start 77, os migrate plan / apply 95 with the --allow-destructive rule, which packages/cli/src/commands/migrate/ implements) or references/bootstrap.md (npx create-objectstack my-app line 84, os dev --ui 186). The file prices at exactly its 6012 ceiling, lowered to the measurement. Holds.
  • skills/objectstack-query/SKILL.md — same shape as ai. Holds.
  • skills/objectstack-ui/SKILL.md — stamp "18.3.0"; byte-identical to the previous head; prices at exactly its 3544 ceiling. Holds.
  • skills/objectstack-upgrade/SKILL.md — stamp "18.3.0"; no pin, exempt by the at the TARGET major rationale the live compatibility: text carries. Holds.
  • skills/objectui/SKILL.md — stamp "18.3.0"; pin @objectstack/spec 18.x stands; byte-identical, and no objectui/** sibling moved. Holds.

Attempts to break it on this head: a skill directory without a SKILL.md (none, eleven and eleven); a nested or extra SKILL.md (none); a stale 18.2.0 under skills/ (none); a pin at a major other than 18 (none); a single-quoted or bare stamp (all double-quoted); a body byte moved beside the stamp in the PR's own diff (none, each file differs from dd6349ec by one line); a body byte moved by main that the catalog ships without a changeset (none, both carried-in hand-authored edits are declared and in the CHANGELOG); a carried-in priced file over its ceiling, or a lowered ceiling above the landed measurement (none, both lowered rows at the measurement); a CEILINGS row on an eval path (none); a SKILL.md sentence that teaches a shape the code at the head refuses or a key it lacks (none, every clause of the ADR-0146 paragraph is pinned above, and the five types it names are exactly the registry's allowEnvironmentOverlay: true rows); a deletion that removed a true rule with no surviving home (none, each has one, named above); a major hidden behind a ! subject (none, all 154 patch or minor); a fixed-group member left out of the version pass (none, 109 for 109); a reader or consumer that moved under the stamp (none); a failure smoke on this sha (none, two success, three cancelled).

Must-fix: none. Should-fix: none on the hits files; the ratchet comment drift and the 6-token unbanked shrink in ③ are comment-level notes on main, and the three-changeset staleness and the field.zod.ts prose note are the seat's calls on timing and on a spec card.

Implemented-by: changeset-release/main
Reviewed-by: session_01AavokzJ5DndAwitDXvKy4U

VERDICT: PASS


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor

triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

Contract-review-claim: session_01AavokzJ5DndAwitDXvKy4U · head 29ca3298c32908b8dff45e8b20cf32355fe3435f · 2026-11-01T19:52Z

The Version PR regenerated past this seat's PASS 6558375205 on 936de789, so the delta re-review is this seat's, at CONTRACT_REVIEW_TIER. ⛔ A review only.


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor

triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 29ca3298c32908b8dff45e8b20cf32355fe3435f
Local-runs: none
Regen-provenance: 6558375205 · 936de78964c0ab0783fec534a66481ae151837d9 → 29ca3298c32908b8dff45e8b20cf32355fe3435f · unexplainedPathsBetween → (empty)
Scope: skills/objectstack-ai/SKILL.md, skills/objectstack-api/SKILL.md, skills/objectstack-automation/SKILL.md, skills/objectstack-data/SKILL.md, skills/objectstack-formula/SKILL.md, skills/objectstack-i18n/SKILL.md, skills/objectstack-platform/SKILL.md, skills/objectstack-query/SKILL.md, skills/objectstack-ui/SKILL.md, skills/objectstack-upgrade/SKILL.md, skills/objectui/SKILL.md + scripts/check-skill-compatibility-version.mjs, scripts/check-skills-token-ratchet.mjs (CEILINGS, pricedTokens, the stamp exclusion), scripts/pm/check-governed-merges.mjs, scripts/pm/record-recognisers.mjs (unexplainedPathsBetween, reviewFace, read at the head and at local db357f6da9, identical), package.json (root version script), .changeset/config.json, .github/workflows/release.yml (version-pr, Validate the post-version tree), .github/workflows/lint.yml (the ratchet and check:skill-compatibility steps), .github/workflows/publish-smoke.yml, .github/workflows/pr-automation.yml (Check Changeset), packages/skills/scripts/sync-catalog.mjs, packages/skills/CHANGELOG.md, packages/spec/package.json, packages/skills/package.json, packages/core/package.json, packages/formula/package.json, packages/runtime/package.json, packages/spec/src/kernel/customization-package.ts, packages/spec/src/kernel/metadata-plugin.zod.ts (DEFAULT_METADATA_TYPE_REGISTRY, allowEnvironmentOverlay), packages/metadata-protocol/src/served-override.ts (isServedOverrideRowOf), packages/metadata-protocol/src/protocol-served-overrides.ts (listServedOverrides, moved), packages/metadata-protocol/src/protocol.ts (servedOverlayRowCandidates, declinesStoredRow with its row parameter, the env-wide list narrowing, the orphan arm, the D11 migration doors; moved), packages/metadata-protocol/src/protocol-packageless-overlay-migration.ts (new), packages/metadata-protocol/src/sys-metadata-repository.ts, packages/runtime/src/domains/packages.ts, packages/objectql/src/protocol-custom-override-effective-read.test.ts, packages/objectql/src/protocol-flow-custom-override.test.ts (new), packages/rest/src/public-form-withdrawal-effective-read.test.ts, packages/cli/src/commands/migrate/ (packageless-overlays.ts, new), skills/objectstack-platform/references/operations.md, skills/objectstack-automation/references/integration-recipes.md, packages/connectors/connector-mcp/src/mcp-provider.ts, packages/connectors/connector-mcp/src/tool-snapshot.ts, packages/spec/src/data/field.zod.ts (relatedList, for ③), .changeset/28412-flow-custom-override-armed.md and .changeset/28413-packageless-overlays.md at the base (for ④)

Delta record. The previous record on this PR is comment 6558375205 (PASS, head 936de789, parent dd6349ec), which continued 6556828324 (PASS, head 0dfbc1c2). The Changesets action's 6-hourly version-pr run (Release run 41334831550, schedule, created 2026-11-01T18:06:05Z) regenerated changeset-release/main on main 5493b884 (2026-11-01T17:34:30Z, PR #28752). The new head is that one commit, chore: version packages (2026-11-01T18:11:03Z, author and committer github-actions[bot]), whose single parent is 5493b884. The PR object's base.sha is 5493b884, so the API base and the merge base agree. The PR reports 1148 files (892 removed, 253 modified, 3 added); git diff --name-only 5493b884 29ca3298 names 1148 files. The run's Version PR maintenance job (124932324030) closed success with every step green: Verify Changesets "fixed" group covers every public package, Render the post-version tree, Validate the post-version tree, Stage the post-version changesets for the read rehearsal, Rehearse the version-PR changeset read on the post-version tree, Assert the read rehearsal found nothing left to version, Restore the pre-version tree, Create or update the "chore: version packages" PR. The commit's time sits inside the job's window (18:06:07Z to 18:11:13Z).

This move IS pure regeneration by the reader's test, and the Regen-provenance: line above records it. unexplainedPathsBetween (the function regenCarry runs; run here with from 936de789, to 29ca3298, base main d9c4cdc4) returns an empty list: 508 files moved between the two heads, and every one is either explained by what main brought between the two bases (44 commits, dd6349ec to 5493b884), carries merge=os-regen, or lies outside the review surface. Every hits file is byte-identical between the two heads, and so is every file under skills/. The pricer scripts/check-skills-token-ratchet.mjs is the same blob (b31e701). The cited gate files are the same blobs: check-skill-compatibility-version.mjs (b333603), sync-catalog.mjs (44ed00a), release.yml (b197935), lint.yml (9afd039), publish-smoke.yml (5e32fe6), pr-automation.yml (da8e4b2), .changeset/config.json (6a18140), root package.json (4e9d2ee), check-governed-merges.mjs (c8fc32a). The PR's own delta against its base under skills/ is 11 files, 11 insertions, 11 deletions, the stamp lines alone. Record 6558375205 therefore carries, and this record is written on top of it for one reason the reader's test cannot see: main moved the CODE a hits file's body teaches (protocol.ts by 374 lines, protocol-served-overrides.ts by 12, the new D11 migration doors and the N-11 flow override), so ④ re-holds the carried-in paragraph against the code on this head. The 400 non-release files in the head move (packages/**, ui/**, content/docs/**, .claude/**) are main's commits under the stamp, in the PR because the head is a child of the new base; none is in the PR's own delta.

① Derived judgments

  • Accept set: unchanged — right (re-judged). The eleven hits hunks are one line each, metadata.version "18.2.0" to "18.3.0", double-quoted as the writer spells them. Against the base 5493b884, each SKILL.md differs by that line alone. No rule text, no schema, no example moves in the PR's own diff.
  • Main's carry-over into the hits files between the heads: none. git diff 936de789 29ca3298 -- skills/ is empty. The ADR-0146 paragraph in skills/objectstack-platform/SKILL.md (line 134, docs(skills,docs): objectstack-platform and the metadata-lifecycle page teach the one effective read of a .custom declared override (ADR-0146 D8) #28586) and the toolsSnapshot paragraph in integration-recipes.md (docs(skills): the automation mcp recipe teaches the providerConfig.toolsSnapshot pin #28597) are the same bytes record 6558375205 placed. The 35 changesets main added between the bases name no @objectstack/skills; none of the 44 commits touches skills/** or the pricer.
  • The pricer did not move, and the arithmetic holds. CEILINGS has 57 rows, zero on an evals/ path. Measured at the head with the pricer's own rule (ceil(utf8 bytes / 4), a stamped SKILL.md less its 20-byte stamp line): 23 rows sit at exactly their ceiling (headroom 0), including platform SKILL.md 24065 bytes, 24045 priced = 6012; automation SKILL.md 25819, 25799 priced = 6450; ui SKILL.md 14194, 14174 priced = 3544; operations.md 12475 = 3119; plugin-development.md 12546 = 3137; seeds.md 6262 = 1566. The rest are under: bootstrap.md 1350 of 1351; integration-recipes.md 9926 = 2482 of 2488; data SKILL.md 6101 of 6123; upgrade SKILL.md 6171 of 6188; i18n SKILL.md 5646 of 6333. Zero rows over. The comment drift the previous record named is still there: line 583 reads == ceil(24055 / 4) above a row of 6012 and a file of 24045 priced bytes. Comment only, main's.
  • Public surface: the catalog's self-declared version moves to 18.3.0 — right, and derived (re-judged). check-skill-compatibility-version.mjs derives metadata.version from CATALOG_VERSION_PACKAGE = '@objectstack/spec'; packages/spec/package.json, packages/skills/package.json, packages/core/package.json, packages/formula/package.json and packages/runtime/package.json all read 18.3.0 at the head. sync-catalog.mjs ships skills/** verbatim into @objectstack/skills@18.3.0. The root version script's last step wrote the eleven lines.
  • The fixed group: unchanged — right. .changeset/config.json is the same blob (109 members). 109 "version": "18.3.0" lines against the base at this head, as at the previous head. The covers-every-public-package step passed on this tree. packages/runtime/package.json differs from the base by its version line alone; its @objectstack/lint dependency is now on both sides.
  • compatibility: lines: unchanged — right. Spec, core and formula are at major 18; every 18.x pin stands; the upgrade skill's EXEMPT text is unchanged.
  • Coverage: complete (re-checked on the new head). git ls-tree on 29ca3298 shows eleven skill directories and eleven SKILL.md files; git grep 18.2.0 over skills/ returns nothing; the only version: lines under skills/*/SKILL.md are the eleven stamps plus version: '1.0.0' inside the platform skill's manifest code block (line 116).
  • Face did not widen. reviewFace on the PR's 1148-file list answers face rules, hits.schema empty, hits.rules the eleven SKILL.md paths, tier CONTRACT_REVIEW_TIER; reviewScopeHits is the same eleven. The same reading as at the two previous heads.
  • Gate verdicts on the head. Check-runs on 29ca3298: zero, the GITHUB_TOKEN shape release.yml describes. 17 check-suites: 12 github-actions at action_required with zero runs ("did not run"), five third-party apps queued. The gate the release commit passes is the version-pr job's Validate the post-version tree, green in run 41334831550 on exactly this tree. The skills token ratchet is not in that job; it runs in lint.yml on main, step Published skills token ratchet (#10473) + its self-test under Lint · docs & code guards, and main's Lint & Type Check push run 41334077032 on 5493b884 closed success at 2026-11-01T18:14:56Z with that step success (the merge_group run 41332221149 on the same sha also success). The priced bytes of every skills/** file are identical between 5493b884 and this head (the stamp line is not priced), so that verdict is this tree's. Commit status publish-smoke / packed-tarballs: read in ③.
  • Outside the hits (lane seat's ACCEPT, named here only). 121 package.json hunks: 109 are the fixed group's version line, the private workspaces outside the group take dependency-driven patch bumps (4.0.103 twice, 0.0.10, 0.3.25, 0.0.43, 0.0.51, 0.0.49, 0.1.11, the two connector apps 0.1.1), packages/create-objectstack/src/templates/blank/package.json moves its @objectstack/* ranges to 18.3.0. The four docs/docker files carry the ghcr.io/objectstack-ai/objectstack:18.3.0 image tags, OS_CLI_VERSION=18.3.0 and @objectstack/cli@18.3.0. 892 changesets removed, 120 CHANGELOGs rewritten (three new: connector-github, connector-stripe, driver-odata). Derived, not reviewed.

② Semver level

  • The PR carries no changeset of its own and no skip-changeset label: it is the consuming side. .changeset/ at the head holds README.md and config.json only; 892 changeset files are removed, which is every .md beside the README at the base 5493b884 (894 entries minus the two kept): the 857 the previous head consumed plus the 35 main added between dd6349ec and 5493b884, none dropped and none edited. Tallied from the removed files' frontmatter: 1330 patch entries, 348 minor entries, 0 major (725 files patch-only, 143 minor-only, 24 mixed). Every consumed changeset's level is at or under minor, the highest level across the fixed group is minor, so the group moves 18.2.0 to 18.3.0, the level the diff publishes. The fixed-group version is 18.3.0 in every one of the 109 members.
  • Breaking-marked subjects, checked for a hidden major. 169 of the 892 changesets open with a ! subject (154 at the previous head, 15 new in the move, among them 28555, 28564, 28594 twice, 28604, 28609, 28627-item-owner-stamp-build-door, 28659, 28663, 28673, harden-connector-undeclared-keys). Every one declares patch or minor (99 patch-only, 58 minor-only, 12 mixed); none declares major. Every one of the 892 carries a Clause-②: line (zero without): 458 plain no, 23 plain yes, the rest long-form no (narrowing) — …, yes (widening …) or yes (narrowing) — … with the arm's reason. No major anywhere; 18.3.0 is right.
  • Metadata-protocol: kinds against AGENTS.md step 3 ("a kind takes at least minor on a package the diff moves"). The 892 read: 723 none, 76 narrowed, 79 added, 14 semantic. 23 narrowed or added changesets grade at least one package patch. In 18 of them the package that carries the protocol move (@objectstack/spec, or the owning package) is minor and the patch entries are consumers: 25767, 25923, 26170, 26548, 26725, 27028, 27123, 27159 (@objectstack/skills patch), 27176, 27347 (@objectstack/skills patch), 27948, 28001, 28100, 28137, 28149, 28407, 28411, 28508-me-permissions-response-contract. In five the package carrying the move is itself graded patch, against the rule as written: 27705-searchable-credential-fields (narrowed, @objectstack/spec patch, @objectstack/objectql patch, @objectstack/lint minor), 28410-override-write-gate (narrowed, @objectstack/spec patch beside three minors), 28534-installed-package-file-ref (narrowed, @objectstack/service-automation patch, sole entry), 28627-item-owner-stamp-shared-judge (narrowed, @objectstack/objectql patch, sole entry), 28659-label-optionless-field-refused (narrowed, @objectstack/objectql patch beside formula and lint minor). Every package named in the 23 is a fixed-group member or a private workspace that moves with the group (@object-ui/app-shell 18.2.0 to 18.3.0), so each publishes at minor whatever its entry says; the published level this PR writes is unaffected. The gradings were judged on the PRs that introduced them; this is a ledger for the seat, not a defect of this tree.
  • The skills package. 56 changesets name @objectstack/skills: 50 patch (two of them beside minor elsewhere, 27159 and 27347), 6 minor (25769-ownership-queue, 27016, 27053, 27069, 27191, 27462), the same 56 as at the previous head: none of the 35 new changesets names the catalog. The @objectstack/skills CHANGELOG at the head carries 56 entries under 18.3.0 (### Minor Changes and ### Patch Changes), byte-identical to the previous head's. The skills CHANGELOG equals the changesets naming the skills package, entry for entry, and both carried-in hand-authored skills edits (8de519f, 28f2e99) are declared.
  • The Check Changeset gate (pr-automation.yml) exempts exactly this head: branch changeset-release/main and author github-actions[bot], pinned together. Same blob as before.
  • Clause-②: line: none on the PR body; the body is the Changesets action's template. The face is the rules face, decided by paths (skills/** in the governed register), so the tier is not read off a Clause-②: line.

③ Boundary flags

  • Author login. The PR's author is github-actions[bot], not objectstack-fleet[bot]: changesets/action opens and force-pushes the PR with the default GITHUB_TOKEN, the login pr-automation.yml pins for the release-PR exemption. Expected identity; no escalation.
  • Zero check-runs. Structural (①); the gate reading is the version-pr validation that produced the head, main's Lint & Type Check on the same skills bytes, and the publish-smoke commit status.
  • Carried item 1, the commit status: green so far, pending again at this reading. On 29ca3298 the context publish-smoke / packed-tarballs has 29 statuses from 14 smoke runs, each started by a main push after the head. Four closed success ("Fresh install of the release candidate: auth + CRUD green"): runs 41337297996 (2026-11-01T18:43:55Z), 41338097452 (18:45:39Z), 41339134217 (18:58:44Z) and 41339435368 (19:01:41Z). Nine were cancelled before a verdict (superseded by a newer smoke under cancel-in-progress). None failed. At the time of this record the newest, run 41344111309 (main d9c4cdc4, started 19:54:37Z), is still installing, so the combined status reads pending. The seat reads the combined status at merge time; a failure would be a new input this record did not see.
  • Carried item 2, staleness against main: resolved for the three it named, and 21 new. Record 6558375205 flagged main five commits ahead with three changesets (28289, 28508-me-permissions-has-any-queue, 28560-field-patch-slot). This head is the regeneration that consumed them: the base moved 44 commits, 35 changesets, no skills/** path. GitHub main is now d9c4cdc4 (2026-11-01T19:30:23Z), 21 commits ahead of 5493b884, with 21 new changesets. Five open with ! or a BREAKING banner (28697 spec/objectql/metadata minor, 28725 and 28726 lint minor, 28746 metadata-protocol/cloud-connection minor, mcp-internal-field-evaluate-positions patch); none declares major; none touches skills/** or the pricer. A merge now leaves those 21 to the next train; release-integrity warns of each. If 18.3.0 is meant to carry them, dispatch Release with refresh_version_pr before merging; the next 6-hourly tick does the same, and each regeneration asks for a fresh record (or a certified Regen-provenance: carry).
  • Carried item 3, the relatedList prose note: not resolved, and not this PR's. packages/spec/src/data/field.zod.ts line 1927 is byte-identical at this head and on main d9c4cdc4: relatedList: true is still described as "a side card in the record's related column (the shared Related tab on the tabbed page)" while rules/record-page.md and the Console teach a right column of panels and a tab row. Still a one-line spec prose card for the seat, if wanted; no catalog sentence at this head moved on it.
  • Carried item 4, the ratchet comment notes: not resolved, unchanged. (a) The arithmetic comment above the platform row still reads ceil(24055 / 4) against a row of 6012 and 24045 priced bytes (①). (b) integration-recipes.md still sits 6 tokens under its 2488 row. Both comment-level, main's; the pricer blob did not move between the heads.
  • Main's Release runs around this head: all green. The schedule run 41334831550 that produced this head and every push Release run after it, from 41335450850 (18:13:02Z) to 41344006851 (19:53:21Z, d9c4cdc4), closed success.
  • Base sha on the PR object. base.sha equals the head's parent (5493b884) at the time of this record. No divergence to place. The GitHub compare of the two heads reads diverged (45 ahead, 1 behind): the previous head is a one-commit branch off dd6349ec, replaced whole; expected for a force-pushed regeneration.
  • A sibling claim on this head: this seat's own. Comment 6563050603 (2026-11-01T19:52Z) is this session's Contract-review-claim: on 29ca3298; no other record or claim names the head.
  • One should-fix found in ④, already carded. The platform skill's ADR-0146 paragraph says a flow override still "waits for its door"; at this head N-11 (feat(service-automation, metadata-protocol): a flow override declared in BASE.custom is the packaged flow, saved, served and armed in place of the base (#28412) #28693, changeset 28412) serves and arms it. Card skills/docs: the ADR-0126 §1.3 promise pages and the skills teach what ADR-0146 D2 delivers — customizations in <base>.custom, __c fields, flow override and "new similar", no package-less overlay #28577 (open: "the skills teach what ADR-0146 D2 delivers — customizations in BASE.custom, __c fields, flow override and 'new similar', no package-less overlay") already owns the sentence. The Version PR cannot carry the fix (the file is regen-owned here); it lands on main and the next regeneration ships it. Not a must-fix: the clause under-teaches a new door, it refuses nothing the code accepts in a way that would make an author write a shape the code rejects, and the sentence dates itself with "today".
  • Auto-merge. Not armed (auto_merge: null), not draft, no labels, mergeable_state: blocked (the queue's required contexts, zero runs). Nothing to disarm.
  • No dev flags and no open_questions exist: bot-authored PR, no card.

④ Design judgment

Judged for every hits file against the code it cites and the scenario it is accepted against: the stamp's reader (check:skill-compatibility, which requires metadata.version to equal @objectstack/spec's workspace version), its pricer (check-skills-token-ratchet, which excludes the one stamp line from the priced bytes and prices no eval fixture or generator-owned file), and its consumer (sync-catalog.mjs, which ships the file verbatim in @objectstack/skills@18.3.0). Reader, pricer and consumer are the same blobs as at 936de789. In this delta no hits file's body moved, so each is judged on the stamp, on nothing having widened the face, and, where the code under a carried-in paragraph moved on main, on that paragraph against the code at this head.

  • skills/objectstack-ai/SKILL.md — stamp "18.3.0"; pin @objectstack/spec 18.x stands against spec 18.3.0; byte-identical to the previous head. Holds.
  • skills/objectstack-api/SKILL.md — same shape. Holds.
  • skills/objectstack-automation/SKILL.md — stamp "18.3.0"; byte-identical to the previous head; prices at exactly its 6450 ceiling. Its connector_action row, which integration-recipes.md points at, is unchanged, and mcp-provider.ts and tool-snapshot.ts did not move between the heads, so the toolsSnapshot paragraph record 6558375205 held against them still holds. Holds.
  • skills/objectstack-data/SKILL.md — stamp "18.3.0"; byte-identical; references/seeds.md line 50 still carries the derived-object sentence and rules/naming.md snake_case. Holds.
  • skills/objectstack-formula/SKILL.md — stamp "18.3.0"; pins @objectstack/spec 18.x and @objectstack/formula 18.x stand; byte-identical. Holds.
  • skills/objectstack-i18n/SKILL.md — stamp "18.3.0"; byte-identical; prices 5646 under 6333. Holds.
  • skills/objectstack-platform/SKILL.md — stamp "18.3.0", one line changed against the base; body byte-identical to the previous head. The ADR-0146 paragraph (line 134) re-held clause by clause against the code at THIS head, where protocol.ts and protocol-served-overrides.ts moved. "Paired writable package hotcrm.custom, which depends on it": customization-package.ts unchanged, customizationPackageId and customizationDependencyRange as before. "A same-named item there with overrides: { package, basedOn } replaces the base's document whole", "honoured only from the pair (the row's package_id)", "never judges basedOn", "ignores any other package's declaration": served-override.ts unchanged (isServedOverrideRowOf tests isCustomizationPairOf(row.package_id, base), refuses a body stamp, records basedOn and never judges it; the partner.ext row answers false); servedOverlayRowCandidates (protocol.ts lines 2896 to 2906 at this head) still puts the pair's declaring row FIRST for a servedOverride read. "Today only for a view, dashboard, report, email_template or translation (page, app, dataset, doc, book, mapping, flow and action wait for their doors)": the five are still exactly the registry's allowEnvironmentOverlay: true rows (metadata-plugin.zod.ts lines 935, 937, 943, 1155, 1156, unchanged), read through OVERLAY_ALLOWED_TYPES and isOverlayAllowed; action is still declined ahead of the predicate. But flow no longer waits: feat(service-automation, metadata-protocol): a flow override declared in BASE.custom is the packaged flow, saved, served and armed in place of the base (#28412) #28693 (changeset 28412-flow-custom-override-armed, @objectstack/metadata-protocol minor, @objectstack/service-automation minor, Clause-②: yes (widening), Metadata-protocol: semantic, consumed by this PR) gives declinesStoredRow(type, name, row) a row parameter that "admits exactly one stored row of a shipped flow name: the shipping package's declared override, a row bound to that package's paired .custom whose body declares overrides.package = the package … That row is the packaged flow now, served over the loader's body for the name"; listServedOverrides (protocol-served-overrides.ts lines 34 to 39) now lists it ("a shipped flow name's declared override is not declined (ADR-0146 D9 item 1): the reads serve it over the base's flow"); protocol-flow-custom-override.test.ts pins the save door admitting it, the per-item publish promoting it, every read of the flow name serving it, the engine arming it and the delete restoring the base. The skill's clause is one door behind the code: it says flow waits, the code serves and arms it. SHOULD-FIX, main's (feat(service-automation, metadata-protocol): a flow override declared in BASE.custom is the packaged flow, saved, served and armed in place of the base (#28412) #28693 shipped no skills/** edit and its changeset names no @objectstack/skills), owned by open card skills/docs: the ADR-0126 §1.3 promise pages and the skills teach what ADR-0146 D2 delivers — customizations in <base>.custom, __c fields, flow override and "new similar", no package-less overlay #28577; a reader who follows the sentence is under-served, not misled into a refused shape. "The env-wide list holds one item per name one code package ships (a dependent's stays under its own ?package=)": protocol.ts line 10525 at this head, the servedOverride && !packageId && request.type !== 'package' narrowing, "Each is still served under its own address". "A package-unbound Setup row still wins over the base's until D11": protocol.ts lines 2904 to 2906 at this head, "A package-unbound row still wins over the code package and over another package's row (ADR-0146 D8 item 1) until the migration moves it into the pair (D11)". D11's migration landed on this base (feat(cli,metadata-protocol): os migrate packageless-overlays moves package-less overlay rows into .custom as declared overrides #28689, changeset 28413-packageless-overlays, os migrate packageless-overlays, Metadata-protocol: added), and that changeset's own Skills-docs: none line names this exact sentence and says it "stays true: the ceremony moves such rows when an operator runs it"; read against packagelessPairLanding and the census doors at protocol.ts lines 9823 to 9850, it does. "An undeclared pair row or a dependent's row is an orphan in the layered read's overlay, effective = the base's": the orphan arm at protocol.ts lines 12258 to 12264 at this head and the effective-read test's ORPHANS case (file unchanged). "May narrow a public form's anonymous intake, never re-open one any honoured body withdrew": public-form-withdrawal-effective-read.test.ts, unchanged. "GET /packages/hotcrm.custom/export carries it with overrides; the base's is unchanged": packages.ts, unchanged. Every clause but the flow one holds; the flow clause is stale against this head, graded should-fix above. The deletions record 6558375205 placed still have their surviving homes (operations.md, bootstrap.md, plugin-development.md, objectstack-data), all unchanged between the heads. operations.md's os migrate row (apply loosens only, --allow-destructive for drops) is unchanged and true; the new os migrate packageless-overlays subcommand is untaught, which skills/docs: the ADR-0126 §1.3 promise pages and the skills teach what ADR-0146 D2 delivers — customizations in <base>.custom, __c fields, flow override and "new similar", no package-less overlay #28577 also covers. The file prices at exactly its 6012 ceiling. Holds, with the should-fix named.
  • skills/objectstack-query/SKILL.md — same shape as ai. Holds.
  • skills/objectstack-ui/SKILL.md — stamp "18.3.0"; byte-identical; prices at exactly its 3544 ceiling. Holds.
  • skills/objectstack-upgrade/SKILL.md — stamp "18.3.0"; no pin, exempt by the at the TARGET major rationale the live compatibility: text carries. Holds.
  • skills/objectui/SKILL.md — stamp "18.3.0"; pin @objectstack/spec 18.x stands; byte-identical, and no objectui/** sibling moved. Holds.

Attempts to break it on this head: a skill directory without a SKILL.md (none, eleven and eleven); a nested or extra SKILL.md (none); a stale 18.2.0 under skills/ (none); a pin at a major other than 18 (none); a single-quoted or bare stamp (all double-quoted); a body byte moved beside the stamp in the PR's own diff (none, each file differs from 5493b884 by one line); a body byte moved by main between the heads (none, skills/ identical); a hand edit hidden in the regeneration (none, unexplainedPathsBetween empty); a carried-in priced file over its ceiling (none, 57 of 57 at or under, 23 at exactly); a CEILINGS row on an eval path (none); a SKILL.md sentence that teaches a shape the code at this head refuses or a key it lacks (none; the one stale sentence runs the other way, teaching a wait the code no longer imposes, should-fix); a major hidden behind a ! subject (none, all 169 patch or minor); a Metadata-protocol: narrowed or added package graded patch that would publish below minor (none, every one moves with the fixed group); a skills CHANGELOG entry without its changeset or a skills changeset without its entry (none, 56 for 56); a fixed-group member left out of the version pass (none, 109 for 109); a reader, pricer or consumer that moved under the stamp (none); a failure smoke on this sha (none, four success, nine cancelled, one in flight).

Must-fix: none. Should-fix: one, outside the PR's own diff and already carded: the platform skill's "flow … wait for their doors" clause is stale against N-11 at this head (#28577 owns it; a skills PR on main, carried by the next regeneration). The ratchet comment drift, the 6-token unbanked shrink, the 21-changeset staleness, the field.zod.ts prose note and the five narrowed-at-patch gradings in ② are notes for the seat on main, not defects of this tree.

Implemented-by: changeset-release/main
Reviewed-by: session_01AavokzJ5DndAwitDXvKy4U

VERDICT: PASS


Generated by Claude Code

@github-actions
github-actions Bot force-pushed the changeset-release/main branch from 29ca329 to 9df8f22 Compare November 2, 2026 00:22
@objectstack-fleet

Copy link
Copy Markdown
Contributor

triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

Contract-review-claim: session_01AavokzJ5DndAwitDXvKy4U · head 9df8f22715c3e94fe1beaad984622925cbb49c1a · 2026-11-02T00:57Z

The delta re-review belongs to the same reviewer (references/contract-review.md). This seat's PASS (6563194383) names 29ca3298, and the Changesets version-pr run regenerated the head on a newer main. Face rules, at CONTRACT_REVIEW_TIER. ⛔ A review only: triage never merges, readies or dispatches this PR.


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor

triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 9df8f22715c3e94fe1beaad984622925cbb49c1a
Local-runs: none
Scope: skills/objectstack-ai/SKILL.md, skills/objectstack-api/SKILL.md, skills/objectstack-automation/SKILL.md, skills/objectstack-data/SKILL.md, skills/objectstack-formula/SKILL.md, skills/objectstack-i18n/SKILL.md, skills/objectstack-platform/SKILL.md, skills/objectstack-query/SKILL.md, skills/objectstack-ui/SKILL.md, skills/objectstack-upgrade/SKILL.md, skills/objectui/SKILL.md + scripts/check-skill-compatibility-version.mjs, scripts/check-skills-token-ratchet.mjs (CEILINGS, the stamp exclusion), scripts/pm/check-governed-merges.mjs, scripts/pm/record-recognisers.mjs (unexplainedPathsBetween, isOutsideReviewSurface, reviewFace, read at the head and at local 892eb668f6, identical blob 4092d00), package.json (root version script), .changeset/config.json, .github/workflows/release.yml (version-pr, Validate the post-version tree), .github/workflows/lint.yml (the ratchet and check:skill-compatibility steps), .github/workflows/publish-smoke.yml, .github/workflows/pr-automation.yml (Check Changeset), packages/skills/scripts/sync-catalog.mjs, packages/skills/CHANGELOG.md, packages/spec/package.json, packages/skills/package.json, packages/core/package.json, packages/formula/package.json, packages/runtime/package.json, packages/spec/src/data/object.zod.ts (ObjectExtensionSchema.fieldPatches, FieldDisplayPatchSchema, FieldOptionDisplayPatchSchema, refuseExtensionFieldPatchKeys, defineObjectExtension; moved), packages/spec/src/data/field-customization.ts (BASE_FIELD_DISPLAY_WHITELIST), packages/metadata-core/src/extension-field-patch-targets.ts (fieldPatchTargetMisses, the picklist-option arm, fieldPatchTargetRefusals), packages/objectql/src/registry.ts (applyFieldPatches, ownFieldsTarget, tenantPatchedDisplayKeys), packages/objectql/src/registry-extension-field-patches.test.ts, packages/cloud-connection/src/marketplace-install-local-plugin.ts (fieldPatchTargetRefusalsOf, UNRUNNABLE_REFUSAL_STATUS), packages/cli/src/commands/validate.ts (step 3a-v), packages/objectql/src/engine.ts (refuseSearchOverrideNamingNoField, assertSearchFieldsAreSearchable), packages/lint/src/rule-explanations.ts (searchable-field-unknown), skills/objectstack-data/rules/indexing.md, skills/objectstack-data/rules/validation.md, packages/spec/src/kernel/customization-package.ts (moved), packages/spec/src/kernel/metadata-plugin.zod.ts (DEFAULT_METADATA_TYPE_REGISTRY, allowEnvironmentOverlay; moved), packages/metadata-protocol/src/served-override.ts, packages/metadata-protocol/src/protocol-served-overrides.ts, packages/metadata-protocol/src/protocol.ts (servedOverlayRowCandidates, declinesStoredRow, the env-wide list narrowing, the orphan arm, packagelessPairLanding; moved), packages/metadata-protocol/src/protocol-packageless-overlay-migration.ts, packages/runtime/src/domains/packages.ts (moved), packages/objectql/src/protocol-custom-override-effective-read.test.ts, packages/rest/src/public-form-withdrawal-effective-read.test.ts, packages/connectors/connector-mcp/src/mcp-provider.ts, packages/connectors/connector-mcp/src/tool-snapshot.ts, packages/spec/src/data/field.zod.ts (relatedList, for ③), .changeset/28730-skill-field-patches.md, .changeset/28806-save-notice-after-suspension-refused.md and .changeset/28799-two-granularities-one-dimension-refused.md at the base (for ②)

Delta record, written as a complete record. The previous record on this PR is comment 6563194383 (PASS, head 29ca3298, parent 5493b884), which continued 6558375205 (PASS, head 936de789) and 6556828324 (PASS, head 0dfbc1c2). The Changesets action's 6-hourly version-pr run (Release run 41366284238, schedule, created 2026-11-02T00:16:47Z) regenerated changeset-release/main on main 00918c886c (2026-11-02T00:00:36Z, PR #28795). The new head is that one commit, chore: version packages (2026-11-02T00:22:09Z, author and committer github-actions[bot]), whose single parent is 00918c886c. The run's Version PR maintenance job (125027017394) closed success with every step green: Verify Changesets "fixed" group covers every public package, Render the post-version tree, Validate the post-version tree, Stage the post-version changesets for the read rehearsal, Rehearse the version-PR changeset read on the post-version tree, Assert the read rehearsal found nothing left to version, Restore the pre-version tree, Create or update the "chore: version packages" PR. The commit's time sits inside the job's window (00:16:50Z to 00:22:24Z). The PR reports 1195 files (939 removed, 253 modified, 3 added); git diff --name-only 00918c886c 9df8f227 names 1195 files, the same census.

This move is NOT pure regeneration by the reader's test, so this record carries no Regen-provenance: line and stands on its own. unexplainedPathsBetween (the function regenCarry runs; run here with from 29ca3298, to 9df8f227, base GitHub main 3e62a22c) returns one path, skills/objectstack-data/SKILL.md: 457 files moved between the two heads, and 456 are explained (main's carry-over between the bases, merge=os-regen, or a prose face outside the review surface), but the data skill is a hits file whose BODY main moved under the stamp (#28795, 20 insertions, 24 deletions, the fieldPatches paragraph) and which the PR's own delta also names (its stamp line), so by the function's own words "this pull request's own reviewed content moved". The refusal is right: the previous record judged a different body for that file. Every other hits file is byte-identical between the heads (git diff 29ca3298 9df8f227 -- skills/ lists the one file), and the reader, pricer and consumer are the same blobs: check-skills-token-ratchet.mjs (b31e701), check-skill-compatibility-version.mjs (b333603), sync-catalog.mjs (44ed00a), release.yml (b197935), lint.yml (9afd039), publish-smoke.yml (5e32fe6), pr-automation.yml (da8e4b2), .changeset/config.json (6a18140), root package.json (4e9d2ee), check-governed-merges.mjs (c8fc32a), record-recognisers.mjs (4092d00). The PR's own delta against its base under skills/ is 11 files, 11 insertions, 11 deletions: git diff 00918c886c 9df8f227 -- skills/ | grep '^[-+] ' yields exactly eleven - version: "18.2.0" and eleven + version: "18.3.0". Main's 51 commits between the bases (5493b884 to 00918c886c) touch skills/** once (#28795) and the pricer, the stamp reader, the catalog shipper and the gate workflows never. The 400-odd non-release files in the head move (ui/packages/** 121, packages/spec/** 46, packages/services/** 36, packages/metadata-protocol/** 25, content/docs/** 19, .claude/skills/** 5, scripts/pm/** 3) are main's commits under the stamp, in the PR because the head is a child of the new base; none is in the PR's own delta.

① Derived judgments

  • Accept set: unchanged — right (re-judged). The eleven hits hunks are one line each, metadata.version "18.2.0" to "18.3.0", double-quoted as the writer spells them. Against the base 00918c886c, each SKILL.md differs by that line alone. No rule text, no schema, no example moves in the PR's own diff.
  • Main's carry-over into the hits files between the heads: one file, the data skill. docs(skills): objectstack-data teaches an object extension's fieldPatches — relabel a vendor field without redeclaring it in fields #28795 (00918c886c, changeset 28730-skill-field-patches, @objectstack/skills patch, Clause-②: no, Metadata-protocol: none) rewrote skills/objectstack-data/SKILL.md: the Object Extension Model section gains fieldPatches in the defineObjectExtension signature and one paragraph on it; the search section's second refusal paragraph is folded into the first (os validate searchable-field-unknown; a request, 400 INVALID_FIELD); the six-line validation-type list collapses to one line; the retired type/partial blockquote and the unique-scope sentence collapse into the rules/indexing.md pointer. Judged in ④. The platform skill's ADR-0146 paragraph (line 134) and integration-recipes.md are the bytes record 6563194383 held.
  • The pricer did not move, and the arithmetic holds. CEILINGS has 57 rows, zero on an evals/ path. Measured at the head with the pricer's own rule (ceil(utf8 bytes / 4), a stamped SKILL.md less its 20-byte stamp line): 23 rows sit at exactly their ceiling (headroom 0), the same 23 as before, including platform SKILL.md 24065 bytes, 24045 priced = 6012; automation SKILL.md 25819, 25799 priced = 6450; ui SKILL.md 14194, 14174 priced = 3544; operations.md 12475 = 3119; plugin-development.md 12546 = 3137; seeds.md 6262 = 1566. The one row that moved: data SKILL.md 24475 bytes, 24455 priced = 6114 of 6123 (headroom 9, was 22; the changeset's "stays under its token ceiling… No ceiling moves" is true). The rest are under: bootstrap.md 1350 of 1351; integration-recipes.md 2482 of 2488; upgrade SKILL.md 6171 of 6188; i18n SKILL.md 5646 of 6333. Zero rows over. The comment drift the previous records named is still there: line 583 reads == ceil(24055 / 4) above a row of 6012 and a file of 24045 priced bytes. Comment only, main's.
  • Public surface: the catalog's self-declared version moves to 18.3.0 — right, and derived (re-judged). check-skill-compatibility-version.mjs derives metadata.version from CATALOG_VERSION_PACKAGE = '@objectstack/spec'; packages/spec/package.json, packages/skills/package.json, packages/core/package.json, packages/formula/package.json and packages/runtime/package.json all read 18.3.0 at the head. sync-catalog.mjs ships skills/** verbatim into @objectstack/skills@18.3.0. The root version script's last step wrote the eleven lines.
  • The fixed group: unchanged — right. .changeset/config.json is the same blob (109 members). 110 package.json files read "version": "18.3.0" at the head and 110 read "version": "18.2.0" at the base: the 109 fixed members plus ui/packages/app-shell/package.json (@object-ui/app-shell, private, which moves with the group as before). The covers-every-public-package step passed on this tree.
  • compatibility: lines: unchanged — right. Spec, core and formula are at major 18; every 18.x pin stands; the upgrade skill's EXEMPT text is unchanged.
  • Coverage: complete (re-checked on the new head). git ls-tree on 9df8f227 shows eleven skill directories and eleven SKILL.md files, none nested; git grep 18.2.0 over skills/ returns nothing; the only version: lines under skills/*/SKILL.md are the eleven stamps plus version: '1.0.0' inside the platform skill's manifest code block (line 116).
  • Face did not widen. reviewFace on the PR's 1195-file list answers face rules, hits.schema empty, hits.rules the eleven SKILL.md paths, tier CONTRACT_REVIEW_TIER; reviewScopeHits is the same eleven. The same reading as at the three previous heads.
  • Gate verdicts on the head. Check-runs on 9df8f227: zero, the GITHUB_TOKEN shape release.yml describes. 17 check-suites: 12 github-actions at action_required with zero runs, five third-party apps queued. The gate the release commit passes is the version-pr job's Validate the post-version tree, green in run 41366284238 on exactly this tree. The skills token ratchet is not in that job; it runs in lint.yml on main under Type Check · source gates, and main's Lint & Type Check push run 41366065879 on 00918c886c closed success at 2026-11-02T00:27:46Z with Published skills token ratchet (#10473) + its self-test and Check SKILL.md compatibility declarations match the workspace majors both success (the merge_group run 41364877984 on the same sha also success). The priced bytes of every skills/** file are identical between 00918c886c and this head (the stamp line is not priced), so that verdict is this tree's. Commit status publish-smoke / packed-tarballs: read in ③.
  • Outside the hits (lane seat's ACCEPT, named here only). 121 package.json hunks: 110 version lines as above, the private workspaces outside the group take dependency-driven patch bumps, packages/create-objectstack templates move their @objectstack/* ranges to 18.3.0. The four docs/docker files (content/docs/deployment/self-hosting.mdx, content/docs/releases/index.mdx, content/docs/upgrading.mdx, docker/README.md) carry the 18.3.0 image tags and CLI pins. 939 changesets removed, 120 CHANGELOGs rewritten (three new: connector-github, connector-stripe, driver-odata). Derived, not reviewed.

② Semver level

  • The PR carries no changeset of its own and no skip-changeset label: it is the consuming side. .changeset/ at the head holds README.md and config.json only; 939 changeset files are removed, which is every .md beside the README at the base 00918c886c (941 entries minus the two kept): the 892 the previous head consumed plus the 47 main added between 5493b884 and 00918c886c, none dropped; two were edited in place between the bases (28560-field-patch-slot.md, the example's option key tech to technology, by docs(spec): key the fieldPatches example option by a value crm_account.industry stores #28827; harden-connector-undeclared-keys.md, one clause of its Unchanged bullet, by fix(spec)!: defineConnector() refuses a top-level key the connector does not declare #28815), both body-only, frontmatter untouched. Tallied from the removed files' frontmatter: 1381 patch entries, 384 minor entries, 0 major (756 files patch-only, 157 minor-only, 26 mixed). Every consumed changeset's level is at or under minor, the highest level across the fixed group is minor, so the group moves 18.2.0 to 18.3.0, the level the diff publishes. The fixed-group version is 18.3.0 in every one of the 109 members.
  • Breaking-marked subjects, checked for a hidden major. 180 of the 939 changesets open with a ! subject or a BREAKING banner (169 at the previous head, 12 new in the move: 28697-object-app-owner-stamp-refused, 28725, 28726, 28733-field-patch-owner-fields-only, 28738-define-connector-closed, 28746-override-gate-bundle-member, 28765, 28799, 28802-bundle-member-base-address, 28806-save-notice-after-suspension-refused, harden-connector-undeclared-keys, mcp-internal-field-evaluate-positions; one earlier ! subject was re-counted by the wider banner regex). Every one declares patch or minor (102 patch-only, 66 minor-only, 12 mixed); none declares major. Every one of the 939 carries a Clause-②: line (zero without): 478 plain no, 23 plain yes, 150 yes (widening), 59 no (narrowing), 30 yes (narrowing), the rest long-form with the arm's reason. No major anywhere; 18.3.0 is right.
  • The two ! commits the brief names, changeset against declaration. feat(spec)! feat(spec)!: refuse at publish a save_notice that a suspending node reaches #28838 (2cba2eb3f1) ships 28806-save-notice-after-suspension-refused.md: @objectstack/spec: minor, Clause-②: no (narrowing), Metadata-protocol: narrowed (a save_notice a suspending node reaches is refused at publish, INVALID_METADATA 422). The ! is the narrowing arm, the kind is narrowed, and AGENTS.md step 3 says a kind takes at least minor on the package the diff moves: minor on spec is exactly right; its Skills-docs: line names follow-up skills(automation): teach the save notice — the save_notice flow node and ctx.notice in hooks (#28251) #28787 (no skills/** file teaches save_notice yet), so no catalog sentence at this head is stale against it. fix(service-analytics)! fix(service-analytics)!: two granularities of one time dimension are refused on every face, not collapsed to the last one #28837 (fa59f78779) ships 28799-two-granularities-one-dimension-refused.md: @objectstack/service-analytics: patch, Clause-②: no (narrowing) — … with the arm's reason, Metadata-protocol: none. A breaking narrowing of a non-protocol accept set (queryDataset refuses two granularities of one time dimension, INVALID_QUERY 400) is, by the same step, "a non-protocol change, widening or breaking, ships patch and keeps its BREAKING banner": patch is right, the banner is there, and the package publishes at minor with the fixed group regardless. Both match their declarations. The other 13 ! commits between the bases (28697, 28725, 28726, 28733, 28738 and harden-connector-undeclared-keys, 28746, 28765, 28802, 28735, 28776, 28727, 28054, mcp-internal-field-evaluate-positions) each carry a (narrowing) arm and patch or minor; none is major.
  • Metadata-protocol: kinds against AGENTS.md step 3. The 939 read: 754 none, 87 narrowed, 82 added, 16 semantic. 25 narrowed or added changesets grade at least one package patch (23 at the previous head plus two new: 28251-save-notice-from-hooks-and-flows, added, spec minor with six consumers patch; 28661-summary-rollup-aggregand-gate, narrowed, lint, metadata-protocol and types minor with rest and runtime patch). In 20 of the 25 the package carrying the protocol move is minor and the patch entries are consumers. The five in which the carrying package is itself graded patch are the same five as before (27705, 28410, 28534, 28627-item-owner-stamp-shared-judge, 28659). Every package named is a fixed-group member or a private workspace that moves with the group, so each publishes at minor whatever its entry says; the published level this PR writes is unaffected. A ledger for the seat, not a defect of this tree.
  • The skills package. 57 changesets name @objectstack/skills: 51 patch, 6 minor (25769-ownership-queue, 27016, 27053, 27069, 27191, 27462); the one new is 28730-skill-field-patches (patch, Clause-②: no, Metadata-protocol: none), the changeset of the one skills/** edit main made between the bases. The @objectstack/skills CHANGELOG at the head carries 57 entries under 18.3.0 (### Minor Changes and ### Patch Changes), 8 lines more than the previous head's: exactly the 00918c8 entry. The skills CHANGELOG equals the changesets naming the skills package, entry for entry, and the carried-in hand-authored skills edit is declared.
  • The Check Changeset gate (pr-automation.yml) exempts exactly this head: branch changeset-release/main and author github-actions[bot], pinned together. Same blob as before.
  • Clause-②: line: none on the PR body; the body is the Changesets action's template. The face is the rules face, decided by paths (skills/** in the governed register), so the tier is not read off a Clause-②: line.

③ Boundary flags

  • Author login. The PR's author is github-actions[bot], not objectstack-fleet[bot]: changesets/action opens and force-pushes the PR with the default GITHUB_TOKEN, the login pr-automation.yml pins for the release-PR exemption. Expected identity; no escalation.
  • Zero check-runs. Structural (①); the gate reading is the version-pr validation that produced the head, main's Lint & Type Check on the same skills bytes, and the publish-smoke commit status.
  • Main's CI is red since the UTC day turned — a release-readiness fact, not this PR's change. p0 4-hourly full run: red on main (CI) #28849 (open, priority:p0, domain:devx, filed 2026-11-02T00:32Z by the 4-hourly full run 41365575482 on 2cba2eb3f1, failure). Signature read off the run's jobs: Dogfood Regression Gate (1/3), (2/3), (3/3), step Boot example apps and exercise real user flows, first error line AssertionError: expected 4 to be 8 in test/audit-key-material.dogfood.test.ts step 2 (os migrate audit-key-material over an 18.0 database), beside no such table: sys_activity__r20261019 in upgrade-18x-harness.dogfood.test.ts. The cause is a clock: sys_activity is storage: { strategy: 'rotation', shards: 14, unit: 'day' }, ensureRotation keeps the last 14 days of Date.now(), and from 2026-11-02 the 18.0 fixture's shard __r20261019 falls outside the window and is dropped at boot. Every main push run that executes the dogfood shards is red from fa59f78779 (2026-11-01T23:55Z) on, including 00918c886c (run 41366065856) and 7f4cbc9d (41366661242); main push runs that skip the shards (6ea8342ac1, 41365645744) are green; Lint & Type Check is green throughout. Nothing in this PR's own delta touches it and nothing here could: the version commit moves version lines, CHANGELOGs, changesets and eleven stamps. But the Release workflow's Full battery green at the version commit job (skipped in the version-pr run, armed on the merge) reads main's battery, so merging 18.3.0 before 4-hourly full run: red on main (CI) #28849 lands publishes nothing until a green full run exists. Named for the seat; not a FAIL reason for the regeneration.
  • Carried item 1, the commit status: green, three for three. On 9df8f227 the context publish-smoke / packed-tarballs has 6 statuses from 3 smoke runs, each started by a main push after the head: 41366833299 (7f4cbc9d, success at 2026-11-02T00:34:16Z), 41367833110 (b95a856e33, 00:35:55Z), 41369038789 (3e62a22c, 00:48:57Z), each "Fresh install of the release candidate: auth + CRUD green". None failed, none cancelled; the combined status reads success at the time of this record. The seat reads the combined status at merge time.
  • Carried item 2, staleness against main: the 21 named are consumed, and 5 commits with 4 changesets are new. Record 6563194383 flagged main 21 commits ahead of 5493b884; this head is the regeneration that consumed them (the base moved 51 commits, 47 changesets added, two edited, one skills/** path). GitHub main is now 3e62a22c (2026-11-02T00:27:09Z), 5 commits ahead of 00918c886c: 7107bde98b (docs ADR-0120, no changeset), 56bd596b2c (docs(skills): objectstack-data rules/lifecycle.md teaches the save notice #28813, 28253-skill-save-notice, @objectstack/skills patch, rules/lifecycle.md), 7f4cbc9d (docs(skills): an email-template override names a locale its base ships; a new locale carries no overrides #28814, 28778-email-template-override-locale, @objectstack/skills patch, platform SKILL.md), b95a856e33 (fix(metadata-protocol,rest,runtime,mcp): the remaining write doors answer a write that landed under a failing roll-up with their own success #28843, 28782, four patch), 3e62a22c (fix(metadata-protocol): the layered read on a base's address answers an email template locale its .custom pair adds with the pair's layer (#28830) #28845, 28830, metadata-protocol patch, Clause-②: yes (widening)). None opens with !, none declares major, none touches the pricer. Two move skills/**, so the next regeneration will again fail the pure-regen test on hits bodies and ask for a fresh record. A merge now leaves those four changesets to the next train; release-integrity warns of each. If 18.3.0 is meant to carry them, dispatch Release with refresh_version_pr before merging; the next 6-hourly tick does the same.
  • Carried item 3, the relatedList prose note: not resolved, and not this PR's. packages/spec/src/data/field.zod.ts is the same blob (641fae6) at this head, at the previous head and on main 3e62a22c: line 1927's docblock still describes relatedList: true as "a side card in the record's related column (the shared Related tab on the tabbed page)" while rules/record-page.md and the Console teach a right column of panels and a tab row. Still a one-line spec prose card for the seat, if wanted.
  • Carried item 4, the ratchet comment notes: not resolved, unchanged. (a) The arithmetic comment above the platform row still reads ceil(24055 / 4) against a row of 6012 and 24045 priced bytes (①). (b) integration-recipes.md still sits 6 tokens under its 2488 row. Both comment-level, main's; the pricer blob did not move.
  • Carried item 5, the platform skill's stale flow clause: fixed on main past this base, still stale at this head. Record 6563194383 graded should-fix the sentence "page, app, dataset, doc, book, mapping, flow and action wait for their doors" (card skills/docs: the ADR-0126 §1.3 promise pages and the skills teach what ADR-0146 D2 delivers — customizations in <base>.custom, __c fields, flow override and "new similar", no package-less overlay #28577). docs(skills): an email-template override names a locale its base ships; a new locale carries no overrides #28814 (7f4cbc9d, one commit past this base) rewrites it to "today only for a view, dashboard, report, email_template, translation or flow (the rest of OVERRIDABLE_METADATA_TYPES wait for their doors)" and adds the email-template locale sentence. This head does not carry that commit (the regeneration ran at 00:16:47Z on 00918c886c); the next regeneration will. Still should-fix here, same grade, same owner; see ④.
  • Base sha on the PR object: three commits past the merge base. The PR object's base.sha is 7f4cbc9d (2026-11-02T00:01:50Z committer date, pushed to main by the queue at about 00:20:55Z, the time of its Release push run), while the head's parent and git merge-base with origin/main is 00918c886c. GitHub recorded the base branch's tip at the force-push moment (00:22:20Z), after the queue had landed 7107bde98b, 56bd596b2c and 7f4cbc9d; the version-pr job checked out 00918c886c at 00:17:12Z. The API's file list (1195) equals git diff 00918c886c 9df8f227 (1195), so the diff GitHub shows is against the merge base; the divergence is a timing artefact, not a content one. The GitHub compare of the two heads reads diverged (52 ahead, 1 behind): the previous head is a one-commit branch off 5493b884, replaced whole; expected for a force-pushed regeneration.
  • Main's Release runs around this head: all green. The schedule run 41366284238 that produced this head and every push Release run after it, 41366661529 (7f4cbc9d), 41367723946 (b95a856e33), 41368920074 (3e62a22c, 00:46:07Z), closed success.
  • A sibling claim on this head: this seat's own. Comment 6566536884 (2026-11-02T00:58Z) is this session's Contract-review-claim: on 9df8f227; no other record or claim names the head.
  • Auto-merge. Not armed (auto_merge: null), not draft, no labels, mergeable_state: blocked (the queue's required contexts, zero runs). Nothing to disarm.
  • No dev flags and no open_questions exist: bot-authored PR, no card.

④ Design judgment

Judged for every hits file against the code it cites and the scenario it is accepted against: the stamp's reader (check:skill-compatibility, which requires metadata.version to equal @objectstack/spec's workspace version), its pricer (check-skills-token-ratchet, which excludes the one stamp line from the priced bytes and prices no eval fixture or generator-owned file), and its consumer (sync-catalog.mjs, which ships the file verbatim in @objectstack/skills@18.3.0). Reader, pricer and consumer are the same blobs as at 29ca3298. In this delta one hits file's body moved (main's #28795 under the data skill's stamp), so that file is judged clause by clause against the code at this head; the other ten are judged on the stamp, on nothing having widened the face, and, where the code under a carried-in paragraph moved on main (protocol.ts by 467 insertions and 29 deletions, metadata-plugin.zod.ts, customization-package.ts, packages.ts, object.zod.ts), on that paragraph against the code at this head.

  • skills/objectstack-ai/SKILL.md — stamp "18.3.0"; pin @objectstack/spec 18.x stands against spec 18.3.0; byte-identical to the previous head. Holds.
  • skills/objectstack-api/SKILL.md — same shape. Holds.
  • skills/objectstack-automation/SKILL.md — stamp "18.3.0"; byte-identical to the previous head; prices at exactly its 6450 ceiling. mcp-provider.ts (f1eea11) and tool-snapshot.ts (088fea0) did not move between the heads, so the toolsSnapshot paragraph in integration-recipes.md that the previous records held against them still holds. Holds.
  • skills/objectstack-data/SKILL.md — stamp "18.3.0", one line changed against the base; body moved by main's docs(skills): objectstack-data teaches an object extension's fieldPatches — relabel a vendor field without redeclaring it in fields #28795 between the heads, re-held here against the code at this head. (i) The signature defineObjectExtension({ extend, fields, fieldPatches, priority }): defineObjectExtension is exported at object.zod.ts line 5010 over ObjectExtensionSchema, whose shape declares extend, fields, fieldPatches (line 4959) and priority (default 200, 0–999, line 4987) as the sentence says. (ii) "A patch carries display keys only (BASE_FIELD_DISPLAY_WHITELIST): label, description, inlineHelpText, placeholder, and an option's label keyed by its stored value": field-customization.ts lines 75 to 80 freeze exactly field: ['label', 'description', 'inlineHelpText', 'placeholder'] and option: ['label']; FieldDisplayPatchSchema and FieldOptionDisplayPatchSchema DERIVE their shapes from the constant (whitelistedPatchShape) and refuse every other FieldSchema key by name with the D6 prescription (structuralKeysOf, lines 4805 to 4845), and options is "a map keyed by each option's stored value" (line 4834). (iii) "the type, values and rules stay the owner's": fieldPatchStructuralPrescription (lines 4717 to 4727) says it in the refusal itself ("type, requiredness, uniqueness, reference target, default, formula, option membership … stay the vendor's"). (iv) "A key the tenant edited keeps the tenant's text": registry.ts applyFieldPatches yields on tenantPatched (ADR-0029 D9.2a, lines 594 to 606), and registry-extension-field-patches.test.ts line 138 pins "yields to a tenant-authored label and option label, and still applies the keys the tenant left alone". (v) "between two extensions the higher priority wins": the schema's own describe (line 4963, "between two extensions the higher priority wins") and the test's docblock ("two patching extenders resolve by priority", line 14). (vi) "A patch naming a field or option value the target lacks is refused at install and by os validate": fieldPatchTargetMisses (metadata-core, line 92) names each field and option miss; the marketplace install door runs fieldPatchTargetRefusalsOf and refuses with fieldPatchTargetRefusalMessage at UNRUNNABLE_REFUSAL_STATUS = 422 (marketplace-install-local-plugin.ts lines 2145 to 2154, 388); validate.ts step 3a-v runs findFieldPatchTargetRefusals, "the install door's own judge", and exits 1 (lines 724 to 745). The fix(objectql,cloud-connection)!: a field patch reaches the owner's own fields only, at the fold and the install door; the install door refuses it with 422 (#28733) #28791 narrowing (28733, consumed here: a patch reaches "the owner's own fields only, at the fold and the install door") is what the skill's "a field the owner declares" already says: ownFieldsTarget (registry.ts line 561) judges the patch against the base's own fields. (vii) "a picklist-bound field's options are never patchable": the picklist-option arm (extension-field-patch-targets.ts lines 111 to 122, "the option labels are the picklist's") and applyFieldPatches' docblock ("A field bound to a picklist is left alone under options"). (viii) The example fieldPatches: { industry: { label: 'Sector', options: { technology: { label: 'Tech' } } } } is the schema's own (object.zod.ts line 4882 and the describe at 4966 to 4968), with the option keyed by its stored value technology as docs(spec): key the fieldPatches example option by a value crm_account.industry stores #28827 corrected it. (ix) The folded search sentence, "refused (os validate searchable-field-unknown; a request, 400 INVALID_FIELD), not silently dropped": the lint rule is searchable-field-unknown at error (reference-integrity-suite.ts line 275, rule-explanations.ts line 2462); the engine's refuseSearchOverrideNamingNoField (14152) and assertSearchFieldsAreSearchable ("refuses the name with a 400", 11625) are the request-side refusal. (x) The deletions have surviving homes: the validation types script, state_machine, format, cross_field, json_schema, conditional are the table in rules/validation.md lines 17 to 22; the protocol-17 retirement of type/partial is rules/indexing.md lines 26 to 33, the 'organization'/'global' scope and "bare unique: true … REFUSED since protocol 18" lines 40 to 75, which the new one-sentence pointer names. What the paragraph does not teach: a __c-spelled fieldPatches key is refused by refuseExtensionFieldPatchKeys ("declare it in fields; it is your own field"); the skill's framing, "a field the owner declares", already excludes it, so an author who follows the sentence never writes that shape. Nothing in the paragraph teaches a key the code lacks or a shape the code refuses. The file prices 6114 of 6123, under its unchanged ceiling. Holds.
  • skills/objectstack-formula/SKILL.md — stamp "18.3.0"; pins @objectstack/spec 18.x and @objectstack/formula 18.x stand; byte-identical. Holds.
  • skills/objectstack-i18n/SKILL.md — stamp "18.3.0"; byte-identical; prices 5646 under 6333. Holds.
  • skills/objectstack-platform/SKILL.md — stamp "18.3.0", one line changed against the base; body byte-identical to the previous head. The ADR-0146 paragraph (line 134) re-held against the code at THIS head, where protocol.ts, metadata-plugin.zod.ts, customization-package.ts and packages.ts moved. "Paired writable package hotcrm.custom, which depends on it": customization-package.ts moved by four lines only, a new object_extension: { disposition: 'excluded', basis: 'adr_0146_d10_extended' } row (metadata-protocol + objectql: an object extension is an authorable item of a writable package — saved and published through the existing doors, registered as 'extend', exported as objectExtensions #28574: an extension is its own item, never a declared override); customizationPackageId and customizationDependencyRange as before. "A same-named item there with overrides: { package, basedOn } replaces the base's document whole", "honoured only from the pair", "never judges basedOn", "ignores any other package's declaration": served-override.ts is the same blob (36f541b); servedOverlayRowCandidates (protocol.ts line 2936 at this head) still puts the pair's declaring row first for a servedOverride read ("[metadata-protocol: one effective read — package-less, base-named, layered, the env-wide list and export serve the .custom declared override, and a withdrawn public form stays withdrawn #28409] The package's declared override first", line 11108). "Today only for a view, dashboard, report, email_template or translation": the five are still exactly the registry's allowEnvironmentOverlay: true rows (metadata-plugin.zod.ts lines 958, 960, 966, 1178, 1179 at this head; the new object_extension row at 828 declares supportsOverlay: false), read through OVERLAY_ALLOWED_TYPES (lines 9954, 9979, 10014). "(page, app, dataset, doc, book, mapping, flow and action wait for their doors)": flow no longer waits. declinesStoredRow(type, name, row?) still takes the row parameter N-11 gave it and admits the pair's declared flow override (listServedOverrides, same blob f2df830, lines 34 to 39: "A shipped flow name's declared override is not declined (ADR-0146 D9 item 1): the reads serve it over the base's flow"); fix(metadata-protocol, service-automation): a declared .custom flow override is armed from the first boot pull (#28717) #28770 (8f294e04b3, changeset 28717-flow-override-first-boot-pull, consumed here) arms it from the first boot pull; feat(studio): customize a read-only base's flow into its pair, with one ledger switch and Restore package original #28824 (693e1003c9, 28570-studio-customize-flow) gives Studio the "customize into its pair" door. SHOULD-FIX, main's, owned by open card skills/docs: the ADR-0126 §1.3 promise pages and the skills teach what ADR-0146 D2 delivers — customizations in <base>.custom, __c fields, flow override and "new similar", no package-less overlay #28577, and already written on main by docs(skills): an email-template override names a locale its base ships; a new locale carries no overrides #28814 one commit past this base (③, carried item 5); a reader who follows the sentence is under-served, not misled into a refused shape. "The env-wide list holds one item per name one code package ships (a dependent's stays under its own ?package=)": protocol.ts line 10664 at this head, the servedOverride && !packageId && request.type !== 'package' narrowing. "A package-unbound Setup row still wins over the base's until D11": lines 2919 to 2921 ("A package-unbound row still wins over the code package and over another package's row (ADR-0146 D8 item 1) until the migration moves it into the pair (D11)"); packagelessPairLanding (line 10009) and protocol-packageless-overlay-migration.ts (same blob 083d33d) are the D11 ceremony, which moves such rows only when an operator runs it, so the sentence stays true. "An undeclared pair row or a dependent's row is an orphan in the layered read's overlay, effective = the base's": the orphan arm at lines 12523 and 12565 at this head (overlay !== null && !orphaned && !this.declinesStoredRow(request.type, request.name, overlayRow)), and the effective-read test (same blob 88180e0). "May narrow a public form's anonymous intake, never re-open one any honoured body withdrew": public-form-withdrawal-effective-read.test.ts, same blob. "GET /packages/hotcrm.custom/export carries it with overrides; the base's is unchanged": packages.ts lines 3101 to 3184 at this head (overrides from listServedOverrides({ packageId: baseId }); "a pair package answers empty overrides and extensions"). What main added under the paragraph that it does not yet say: an email template is one item per (name, locale), an override names a locale the base ships, a locale the base does not ship is added without overrides (fix(metadata-protocol)!: the override write gate judges an email template by its locale, so a pair's override of a locale the base does not ship is refused (#28746) #28777, fix(metadata-protocol)!: an email template locale added in a .custom pair is listed and sent on the base's address; a dependent's added locale stays under its own package (#28802) #28828, consumed here; taught by docs(skills): an email-template override names a locale its base ships; a new locale carries no overrides #28814 past the base). Under-teaching, the same grade, the same owner. Every clause but the flow one holds. The file prices at exactly its 6012 ceiling. Holds, with the should-fix named.
  • skills/objectstack-query/SKILL.md — same shape as ai. Holds.
  • skills/objectstack-ui/SKILL.md — stamp "18.3.0"; byte-identical; prices at exactly its 3544 ceiling. Holds.
  • skills/objectstack-upgrade/SKILL.md — stamp "18.3.0"; no pin, exempt by the at the TARGET major rationale the live compatibility: text carries. Holds.
  • skills/objectui/SKILL.md — stamp "18.3.0"; pin @objectstack/spec 18.x stands; byte-identical, and no objectui/** sibling moved. Holds.

Attempts to break it on this head: a skill directory without a SKILL.md (none, eleven and eleven); a nested or extra SKILL.md (none); a stale 18.2.0 under skills/ (none); a pin at a major other than 18 (none); a single-quoted or bare stamp (all double-quoted); a body byte moved beside the stamp in the PR's own diff (none, each file differs from 00918c886c by one line); a body byte moved by main between the heads that the record had not judged (one file, the data skill, judged above clause by clause); a hand edit hidden in the regeneration (none: the one path unexplainedPathsBetween returns is main's #28795, commit 00918c886c, with its changeset and CHANGELOG entry, not a hand edit on the branch); a carried-in priced file over its ceiling (none, 57 of 57 at or under, 23 at exactly); a CEILINGS row on an eval path (none); a SKILL.md sentence that teaches a shape the code at this head refuses or a key it lacks (none; the one stale sentence runs the other way, teaching a wait the code no longer imposes, should-fix); a major hidden behind a ! subject (none, all 180 patch or minor); a ! commit whose changeset omits the (narrowing) arm or grades a narrowed kind patch on the carrying package (none of the 15 between the bases); a Metadata-protocol: narrowed or added package graded patch that would publish below minor (none, every one moves with the fixed group); a skills CHANGELOG entry without its changeset or a skills changeset without its entry (none, 57 for 57); a fixed-group member left out of the version pass (none, 109 for 109); a reader, pricer or consumer that moved under the stamp (none); a failure smoke on this sha (none, three success).

Must-fix: none. Should-fix: one, outside the PR's own diff, already carded and already fixed on main past this base: the platform skill's "flow … wait for their doors" clause is stale against N-11 at this head (#28577 owns it; #28814 on main rewrites it; the next regeneration ships it and asks for a fresh record). The main-red p0 #28849 is a release-readiness fact the seat reads before publishing, not a defect of this tree. The ratchet comment drift, the 6-token unbanked shrink, the 4-changeset staleness, the field.zod.ts prose note, the three-commit base.sha offset and the five narrowed-at-patch gradings in ② are notes for the seat on main, not defects of this tree.

Implemented-by: changeset-release/main
Reviewed-by: session_01AavokzJ5DndAwitDXvKy4U

VERDICT: PASS


Generated by Claude Code


Generated by Claude Code

@github-actions
github-actions Bot force-pushed the changeset-release/main branch from 9df8f22 to 1f3b7fb Compare November 2, 2026 06:17
@objectstack-fleet

Copy link
Copy Markdown
Contributor

triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

Contract-review-claim: session_01AavokzJ5DndAwitDXvKy4U · head 1f3b7fbd503c385931f7abb8f18c3dd7dd29a803 · 2026-11-02T07:00Z

The delta re-review belongs to the same reviewer: this seat's PASS (6566696032) names 9df8f227, and the Changesets version-pr run regenerated the head. Face rules, at CONTRACT_REVIEW_TIER. ⛔ A review only: triage never merges, readies or dispatches this PR.


Generated by Claude Code

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants