Skip to content

docs(skills,automation): a connector_action input is judged against the action's inputSchema before dispatch, refused as VALIDATION_ERROR - #28170

Merged
os-zhuang merged 4 commits into
mainfrom
claude/project-thread-bcip5d
Oct 31, 2026
Merged

os-zhuang merged 4 commits into
mainfrom
claude/project-thread-bcip5d

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Elon · project thread

domain:skills#2 · os-elon-musk · session_016WV4cwp1Wc6nB6ePmS4ePn

Fixes #28041

Clause-②: no
Metadata-protocol: none

维护者速读

What changes

  • skills/objectstack-automation/SKILL.md, the connector_action row: the evaluated input is judged against the action's inputSchema (required, type, properties, items) before dispatch; a breach fails the step VALIDATION_ERROR (fault-routable) and nothing is sent; os validate does not judge it yet (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).
  • references/integration-recipes.md, Holds bullet 2: "any other value sent as written" becomes "kept as written", then the same judgment with OpenAPI nullable, null-on-optional read as absent, the per-path naming, and the int() cast for a string-held id (path: { dialect: 'cel', source: '{"petId": int(record.vendor_id)}' }, the shape the merged suite pins at connector-input-schema.test.ts:208).
  • content/docs/automation/connectors.mdx, Failure modes at a glance: one row for the refusal, with the code, the routing, the remedy (int() / double() / bool()), the listing route and the os validate note. The cross-domain exception is triage 6521031879.

Wording measured against the merged code (ec7e15abc, packages/services/service-automation/src/builtin/connector-nodes.ts:126-163 and collectInputSchemaViolations), not the card's paraphrase. Shipped message: connector_action '<node>': input for '<connector>.<action>' does not match the action's inputSchema — <violations>. Nothing was sent. Fix connectorConfig.input so it satisfies the inputSchema GET /api/v1/automation/connectors lists for this action. plus, for text where a number or boolean is declared, A text value for an integer, number or boolean parameter is not converted: cast it in a CEL envelope with int(), double() or bool(). The result carries code: 'VALIDATION_ERROR' and the default runtime class, so a fault edge receives it (pinned in the same suite). #27968 is still open, so the os validate note stays.

Paid for in the same file (restatement only, each with a surviving home)

SKILL.md: the approval row's "(from plugin-approvals)" (the requires table row says it), "never an http node holding a credential" in § Integrations (the http row says it), the filter-operand "(not fault-routable)" (the ROUTES table lists that case as not routing), and "notify delivers, connector_action reaches a vendor, a function computes" (the node rows and the PURE-compute paragraph below say it). 6457 → 6452 tokens.

integration-recipes.md: recipe 1's "trimming still keeps the package small" (recipe 1's comment says to trim), recipe 4's two comments "an inbound post carries no trigger user" (recipe 1 teaches the same runAs reason) and "never a literal secret" (the intro says the hook secret goes to the deployment), recipe 5's "// inline OpenAPI 3.x" (the next line spells openapi: '3.0.3' inline), the OAuth bullet's "Declare the connector, fields and flows, mark the integration blocked …, and say so" (the section heading says it), and "with its input schema, visible" after recipe 5 (bullet 2 now carries the schema). 2236 → 2236 tokens, headroom 0. No ceiling moved; scripts/check-skills-token-ratchet.mjs is untouched.

Verification

  • node scripts/check-skills-token-ratchet.mjs: exit 0 (SKILL.md 6452/6457, integration-recipes.md 2236/2236). pnpm check:pm-skill-ratchet exit 0.
  • Gates: dispatch-gates --commands at the committed head f2cd1d93 derives 60 families; all 60 run in a fresh worktree after pnpm install --frozen-lockfile --ignore-scripts and builds of @objectstack/lint... and @objectstack/client-react..., exit codes recorded per command. 59 exit 0 (including check:pm-skill-id-lint, check:skill-docs, check:skill-examples, check:skill-refs, check:docs, check:doc-anchors, check:doc-formula-expressions, check:skill-identifier-liveness). check:dual-build-cjs-loads exits 3 (needs every dist), NOT MEASURED. --ran reconciles 60 derived / 59 run / 1 NOT-MEASURED / 0 UNRUN; the derivation re-run at the final head is identical.
  • No changeset derived: no published package is touched, so skip-changeset.
  • Landing tier: check-governed-merges.mjs --test reads 2 of 3 paths on the register (skills/**), Tier H. The register's reading at PR time is the seat's.
  • Not measured locally: repo-wide pnpm lint, the type-check lanes, and the docs site build (CI's).

Human Minimum

Each item is one rule from
CONTRIBUTING.md › Human Minimum,
which links the AGENTS.md text that states it.

  • 1. Schemas start as Zod; packages/spec holds no runtime logic. (not touched)
  • 2. Every name I added uses the casing for its kind.
  • 3. No formatter ran; the derived lint families pass.
  • 4. One issue, one branch off an up-to-date main, one pull request.
  • 5. A change that publishes carries a changeset, and both declaration lines are filled in here and in the changeset. (no published package: skip-changeset)
  • 6. packages/spec touched: its generated artifacts are regenerated and committed. (not touched)
  • 7. No hand edits to content/docs/references/, packages/*/CHANGELOG.md or content/docs/releases/.
  • 8. Title, body and comments are in English (the 维护者速读 block is the one Chinese channel).
  • The Before Submitting list in CONTRIBUTING.md is done.

🤖 Generated with Claude Code

https://claude.ai/code/session_016WV4cwp1Wc6nB6ePmS4ePn

…he action's inputSchema before dispatch

After #27995 (PR #28035) the evaluated connectorConfig.input is checked
against the action's declared inputSchema (required, type with OpenAPI
nullable, properties, items) and a breach fails the step as
VALIDATION_ERROR, fault-routable, with nothing sent. The automation
skill's connector_action row and the integration recipes still taught
the input as sent unchecked, and the connectors docs page had no
failure-modes row for the refusal.

- SKILL.md: the connector_action row says what is judged, the code, that
  a fault edge routes it and that nothing is sent; os validate still does
  not judge the input (#27968).
- integration-recipes.md: the same, plus null-on-optional reads as
  absent and the int() cast for a string-held id.
- connectors.mdx: a failure-modes row with the code and the remedy.

The new text is paid for by same-file deletion of restatement, so both
skill files stay within their token ceilings without a ratchet change.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016WV4cwp1Wc6nB6ePmS4ePn
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 30, 2026
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Oct 30, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:skills#2 · os-elon-musk · session_016WV4d1QkPVVzNz3FJqb2iS

Contract-review-claim: session_016WV4d1QkPVVzNz3FJqb2iS · head f2cd1d9 · 2026-10-30T15:08Z

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:skills#2 · os-elon-musk · session_016WV4d1QkPVVzNz3FJqb2iS

Contract review

Head-sha: f2cd1d931c8e90319c1dac010657a26764553428
Served-tier: CONTRACT_REVIEW_TIER
Local-runs: probe — the skills ratchet family (node scripts/check-skills-token-ratchet.mjs on the head worktree and on a detached worktree at the base 27e0bd584, node scripts/pm/check-skill-line-ratchet.mjs, node scripts/pm/check-skill-id-lint.mjs, node scripts/check-skill-identifier-liveness.mjs, pnpm check:doc-anchors, node scripts/check-docs-section-name.mjs, pnpm --filter @objectstack/spec run check:skill-docs and check:skill-refs, and node scripts/pm/check-governed-merges.mjs --pr 28170) was executed locally, because the one gate this diff can turn red is a per-file token count that the dev paid down to a headroom of 0 and 5 and no check-run prints as a number; check:docs and check:doc-formula-expressions stopped at a prerequisite (exit 1 for a missing packages/spec/json-schema, exit 3 for an unbuilt @objectstack/formula) and are NOT MEASURED here, read from CI; nothing else was built or run.
Scope: skills/objectstack-automation/SKILL.md, skills/objectstack-automation/references/integration-recipes.md + content/docs/automation/connectors.mdx (the cross-domain row, triage 6521031879), packages/services/service-automation/src/builtin/connector-nodes.ts (the #27995 block at :126-163 and collectInputSchemaViolations, jsonKindOf, matchesType, JUDGED_TYPES, MAX_NAMED_VIOLATIONS), packages/services/service-automation/src/builtin/connector-input-schema.test.ts (the pins, read not run), packages/services/service-automation/src/engine.ts (NodeFailureClass, NodeExecutionResult.errorClass, the runtime default), packages/formula/src/validate.ts (the CEL standard function list, int), skills/objectstack-automation/evals/integrations-declared.json (eval 1 and eval 3 rubrics), scripts/check-skills-token-ratchet.mjs and scripts/pm/check-skill-line-ratchet.mjs (the gates that hold the ceilings), PR #28150 (head 6a06a420b, its diff on flow.zod.ts, engine.ts and references/automation/flow.mdx, its review 6525595405) and card #28162 (triage 6525897453), for the coordinator's three questions

Inputs: git diff 27e0bd584..f2cd1d931 (3 files, +27 / −23, one commit, author Claude, trailers Co-authored-by and Claude-Session present, no model name, no Refs); git merge-base pr-28170 origin/main is 27e0bd584; origin/main had moved eight commits to 9f13ee815 at review time and none of them touches the three files, connector-nodes.ts or scripts/pm; the PR body and its one comment (6526073574, the contract-review claim naming this session and this head; no reviews, no hold, no hand-off); card #28041 (body; triage 6521031879 and 6524854844; claim 6525243871); PR #28035 (body, 5-file list, merged 2026-10-30T12:13Z as ec7e15abc, an ancestor of the base; its contract review 6520142501 whose ①1 and ①3 findings the merged code answers); #27968 (open, pm:dispatched, domain:spec); PR #28150 (open, ready, not draft, not merged, head 6a06a420b, Fixes #27968, its 22-file list carries no skills/** path); card #28162 (open, pm:blocked on #28150); the dispatch order and the dev report at /mnt/project-files/skills-lane-seat2/; .claude/skills/pm-dispatch/references/contract-review.md and review-checklist.md; the code at origin/main for every claim the new sentences make; the head's check-runs (three polls, last at 2026-10-30T15:18Z).

① Derived judgments

  1. Accept set: unchanged — correct. The diff is prose only: two governed skill files and one docs page. No schema, export, type or runtime behaviour moves; Clause-②: no and Metadata-protocol: none hold. The register reads 2 of 3 paths as skills/**, Tier H, 50 changed lines under the human-merge threshold; the reading is the dev's.
  2. What is judged — the new text names the shipped subset exactly. collectInputSchemaViolations (connector-nodes.ts :248-298) judges required (the object's own required list, a missing or undefined key), type (a string or a type list, every member in JUDGED_TYPES, else unjudged; integer is Number.isInteger or a bigint; nullable: true admits null, :257), properties (descent, :288-293) and items (descent by index, :295-296). The row's "required, type, properties, items", the recipe's "type (with OpenAPI nullable)" and the docs row's "a missing required parameter, a wrong type" are that list. Everything outside the subset ($ref, combinators, enum, format, bounds, additionalProperties) never refuses, and the new text claims nothing about it.
  3. When — "once evaluated ... before dispatch" is the code's order. resolveValueSlotMap (:124) runs first, the judgment (:138-143) next, handler(input, handlerCtx) (:168) only on an empty violation list. The pins sent being [] in every refusal test. "Nothing sent" / "nothing is sent" is true, and the shipped message says it in the same words ("Nothing was sent.", :154).
  4. The code and its routing — right. The result is { success: false, code: 'VALIDATION_ERROR', error } (:147-150) with no errorClass, and NodeExecutionResult.errorClass "defaults to runtime" (engine.ts :401-407; the NodeFailureClass docblock: "A declared fault edge routes it"). The test pins a fault edge receiving $error.code === 'VALIDATION_ERROR' (:154-161, :193-199). "fault-routable" in both skill files and "a fault edge or try_catch can route it" in the docs row are true.
  5. null on an optional parameter counts as absent — right, and the recipe says exactly that. :291 if (record[key] === null && !required.has(key)) continue;, pinned at test :248. The recipe's "null on an optional parameter is absent" is this line; a null on a REQUIRED parameter is still refused (:216-221), and the recipe does not say otherwise.
  6. Text is never converted; the CEL cast is int() — right spelling. :261-263 sets textForScalar when a string meets integer, number or boolean, and the message then appends the cast prescription naming int(), double() or bool() (:159-161). int is in the CEL standard function list (packages/formula/src/validate.ts :1297, :1200), and the merged suite at :208 pins {"petId": int(rec.idText)} dispatching with the number 7. The recipe's path: { dialect: 'cel', source: '{"petId": int(record.vendor_id)}' } is that pinned shape with the record field renamed; the docs row's "cast it in a CEL envelope (int(), double(), bool())" is the message's own list.
  7. Naming each path — right. Lines are missing required 'path.petId' (with the required children of a missing section, :275-281) and 'query.verbose' must be boolean, got string (:260), capped at MAX_NAMED_VIOLATIONS = 5 then "; and N more". The recipe's "naming each path" and the docs row's "naming each parameter path" are true; neither claims the cap, which is fine.
  8. Quoted message text — the PR body quotes it verbatim; the diff quotes none of it. The PR body's message (with NODE, CONNECTOR and ACTION placeholders) is the template at :151-161 character for character, including "does not match the action's inputSchema —", "Nothing was sent.", "Fix connectorConfig.input so it satisfies the inputSchema GET /api/v1/automation/connectors lists for this action." and the cast sentence. The three files quote only the code VALIDATION_ERROR and the route GET /api/v1/automation/connectors, both verbatim.
  9. "os validate does not judge it yet" — true today, imprecise, and the one must-fix (the coordinator's question (a)). On origin/main neither door judges connectorConfig.input at all: 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 is open, so a literal input: {} for getPet registers and validates and is refused only at run time (PR fix(service-automation)!: a connector_action call whose input breaks the action's declared inputSchema fails before dispatch, naming each parameter #28035 body, inventory 4). Two different checks are in play, and the diff's sentence does not say which one it means:
  10. The restatement cuts — restatement, each with a surviving home, one why lost. Read sentence by sentence on the head:
  • SKILL.md approval row "(from plugin-approvals)": the requires table :341 says approvals → approval / approval_revise (plugin-approvals). Kept.
  • SKILL.md § Integrations "never an http node holding a credential": the http row :86 says "never a credential there: a credential means a declared connector called via connector_action". Kept.
  • SKILL.md null-operand bullet "(not fault-routable)": the ROUTES table :141 lists "filter operand that evaluated to null" under "Does NOT route (fatal either way)". Kept.
  • SKILL.md "notify delivers, connector_action reaches a vendor, a function computes": the node rows and the PURE-compute paragraph :249 carry each clause. Kept.
  • Recipe 1 "trimming still keeps the package small": recipe 1's comment :39-40 prescribes the trim ("Trim the vendor's OpenAPI 3.x document to the operations the app calls and ship it in the package"). The prescription is kept; the size rationale is a why, not a rule.
  • Recipe 4 "// an inbound post carries no trigger user": runAs: 'system' stays on the api flow :111, and recipe 1 :49 teaches "a scheduled run has no trigger user". The prescription is kept; the api-flow reason now has no home (should-fix 2).
  • Recipe 4 "// never a literal secret": the intro :10-11 ("an api flow's hook secret goes to the deployment and to the sender") and the secretRef key itself. Kept.
  • Recipe 5 "// inline OpenAPI 3.x": the next line spells openapi: '3.0.3' inline. Kept.
  • The OAuth bullet's "Declare the connector, fields and flows, mark the integration blocked ..., and say so": the section heading :149 "Not yet — declare the rest, mark the integration blocked, write no plugin" is the rule; the bullet keeps "Blocked on the platform's outbound-OAuth card". Kept.
  • "with its input schema, visible" after recipe 5: Holds bullet 2 now carries the schema and its judgment. Kept.
  1. Eval corpus — the dev's deviation names the wrong line; the real stale rubric is older than this PR (should-fix 3). evals/integrations-declared.json nowhere contains "trimming still keeps the package small"; eval 1's rubric says "a trimmed, packaged OpenAPI 3.x document", which recipe 1 still teaches, so that cut breaks nothing. What eval 1's expected_output does say is "connectorConfig.input is sent as written, so a per-contract payload waits on the platform too" — false on main since automation: a connector_action node's connectorConfig.input is handed to the provider as written — a CEL envelope there passes os validate and is never evaluated, so a flow cannot send a per-record value to a declarative connector #27327 (a CEL envelope is evaluated) and now contradicted by the recipe's own sentence ("kept as written ... judged ... before dispatch"). It is a rubric line, not a must_contain token (those are defineConnector, provider: 'openapi', credentialRef, connector_action, type: 'api', secretRef, Swagger 2.0, blocked, all still taught), so grading by tokens is unaffected; a rubric-reading grader is steered to reward a stale claim. Pre-existing, outside the surface, not caused by this diff — a follow-up, not a must-fix. In the same rubric, "the openapi provider has no include key, so the trimmed document is the allowlist" contradicts recipe 1 on main (:70-72, providerConfig.include allowlists operation keys); same carrier.
  2. Ratchets and lint hold on the head. check-skills-token-ratchet: SKILL.md 6457 → 6452 of 6457 (headroom 5), integration-recipes.md 2236 → 2236 of 2236 (headroom 0); the base worktree reads 6457 and 2236, so the dev's before/after numbers are exact and no ceiling moved (scripts/check-skills-token-ratchet.mjs is not in the diff). check-skill-line-ratchet exit 0; check-skill-id-lint 105 files clean; check-skill-identifier-liveness OK (486 citations); check:doc-anchors 832 fragment links resolve; check-docs-section-name exit 0; check:skill-docs and check:skill-refs in sync; check-doc-route-spelling --advisory clean (the docs row's GET /api/v1/automation/connectors spells the ledger row). Check Documentation Links is success on the head.
  3. The connectors.mdx row fits the table. "Failure modes at a glance" is a two-column table (You wrote / it happened | What you get); the new row has two cells and the pipe count of its neighbours. It sits between the "Wrong spec URL" row and the "runtime reload" row; the table's preamble frames boot-time faults, but the reload row already carries a non-boot case, so a run-time refusal row is in character (④ notes the placement).
  4. Consistency elsewhere. git grep on origin/main over skills/**, content/docs/** and docs/adr/** for "sent as written", "as written", "does not judge", "unchecked", "inputSchema" finds no third sentence that calls the input unchecked: the only two are the ones this diff rewrites. content/docs/automation/flows.mdx :146 ("Declared input parameter types, for Studio form generation and runtime validation") now reads true rather than aspirational. Outside the three faces, packages/spec/src/automation/flow.zod.ts :950 ("handed to the action as written: no template is read there") and PR fix(spec,service-automation,lint)!: registration and validate judge a connector_action's connectorConfig.input value slot #28150's rewritten describe text ("Each value is a literal, handed to the action as written, or a CEL value envelope ...") speak of template interpolation, not of the schema check; they are not false, and they are fix(spec,service-automation,lint)!: registration and validate judge a connector_action's connectorConfig.input value slot #28150's and skills(automation): the connector input recipe still says os validate does not judge connectorConfig.input, which PR #28150 makes false #28162's, not this PR's.
  5. PR body declarations. Fixes #28041 on its own line; no closing keyword beside any other open card number (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 skills(automation): the connector input recipe still says os validate does not judge connectorConfig.input, which PR #28150 makes false #28162 appear only as plain references — skills(automation): the connector input recipe still says os validate does not judge connectorConfig.input, which PR #28150 makes false #28162 does not appear at all). Clause-②: no, Metadata-protocol: none, six ## 维护者速读 lines with the last saying a contract review is owed, Tier H, a governed approver. Labels documentation, size/s, skip-changeset; author objectstack-fleet[bot]; draft; base main. The shipped message is quoted in the body verbatim (①.8).

② Semver level

No release. skip-changeset is right: no published package's files[] ships skills/** or content/docs/** (the skills catalog is governed, not packaged), dispatch-gates derived no changeset family, and the Check Changeset check-run is success on this head. Clause-②: no is right: no narrowing is declared or present, and the narrowing this text documents (PR #28035) carried its own Clause-②: no (narrowing) and changeset.

③ Boundary flags

④ Design judgment

Rules face, the two skill files, against the code they cite and the scenario they are accepted against (an AI author wiring a connector_action over an OpenAPI action with a required integer parameter held as text):

  • SKILL.md :88 — holds against the code; one clause imprecise (must-fix 1). The row now teaches the author the four judged keywords, the failure code, that a fault edge can catch it and that nothing reaches the vendor — each anchored to a line of connector-nodes.ts. The row stays one line, within its table, and 5 tokens under the ceiling; nothing it dropped was a rule. The os validate clause is the only sentence whose truth depends on the landing order of an open PR.
  • integration-recipes.md Holds bullet 2 — holds; the cast example is the pinned one. "kept as written" over "sent as written" is the exact correction the fix(service-automation)!: a connector_action call whose input breaks the action's declared inputSchema fails before dispatch, naming each parameter #28035 review asked for (its Skills-docs line, "sent as written" falsified); the bullet then gives the author the one thing the error message cannot — the CEL spelling before the first run — and the shape is the merged test's own (:208). null-on-optional is the fix(service-automation)!: a connector_action call whose input breaks the action's declared inputSchema fails before dispatch, naming each parameter #28035 review's ①1 must-fix, now on main and now taught; the cast is its ①3, now the shipped prescription. The eval prompts (DocuSign, Stripe, legacy ERP) still resolve to the same recipes; eval 1's rubric is the stale piece (①.11), not the recipe.
  • connectors.mdx row (prose face, the seat's ACCEPT; read for ④ because the governed sentences point at it). Code, routing, remedy and listing route are the message's; it is the only place a human reader learns the remedy list. Placement under a boot-faults preamble is tolerable given the reload row; an editor may one day split run-time rows out. Its os validate clause is the one site skills(automation): the connector input recipe still says os validate does not judge connectorConfig.input, which PR #28150 makes false #28162 does not cover (must-fix 1).
  • The restatement cuts as a method. Paying for a rule with same-file restatement is what the ratchet exists to force, and every removed sentence has a surviving prescription (①.10). The one real loss is a why (recipe 4's runAs reason), carried as should-fix 2 because the ratchet leaves no room for it today.
  • Cited code was read to judge the prose, not reviewed. Nothing in connector-nodes.ts or the test file is under review here.

Implemented-by: claude/project-thread-bcip5d
Reviewed-by: session_016WV4d1QkPVVzNz3FJqb2iS

VERDICT: FAIL

Must-fix:

  1. (this PR, all three files) Name the check os validate does not perform, so the sentence is true whether fix(spec,service-automation,lint)!: registration and validate judge a connector_action's connectorConfig.input value slot #28150 lands before or after this PR: SKILL.md :88 "os validate does not judge the inputSchema fit yet", the recipe's last sentence of Holds bullet 2 the same, and the connectors.mdx row "os validate does not judge the input against the inputSchema yet". SKILL.md has 5 tokens of headroom; the recipe has 0 and needs one more same-file restatement cut of three to five tokens, chosen by the dev on the same rule as the others (a restatement whose prescription survives elsewhere in the file, named in the PR body) and not a rule such as the OAuth bullet's bearer-ref sentence or an answer shape; the docs page is unpriced. A delta review on the new head by the same reviewer closes it.

Should-fix:

  1. (this PR, if the recipe cut for must-fix 1 lands near it) Keep "({…}, {{ }} are literal text)" in Holds bullet 2 untouched: it is true today and is the exact clause skills(automation): the connector input recipe still says os validate does not judge connectorConfig.input, which PR #28150 makes false #28162 rewrites after fix(spec,service-automation,lint)!: registration and validate judge a connector_action's connectorConfig.input value slot #28150; cutting it now would hand skills(automation): the connector input recipe still says os validate does not judge connectorConfig.input, which PR #28150 makes false #28162 a different base.
  2. (carrier: skills(automation): the connector input recipe still says os validate does not judge connectorConfig.input, which PR #28150 makes false #28162, which already reopens the recipe) Restore the api-flow runAs reason in recipe 4 in two or three words ("no trigger user") when skills(automation): the connector input recipe still says os validate does not judge connectorConfig.input, which PR #28150 makes false #28162 next spends tokens there; today only the scheduled-run reason in recipe 1 survives.
  3. (carrier: skills(automation): the connector input recipe still says os validate does not judge connectorConfig.input, which PR #28150 makes false #28162, widen its scope by one file) skills/objectstack-automation/evals/integrations-declared.json eval 1 expected_output: replace "connectorConfig.input is sent as written, so a per-contract payload waits on the platform too" with the value-slot plus schema-check truth (a per-contract payload is a CEL envelope, judged against the action's inputSchema before dispatch), and drop "the openapi provider has no include key" (recipe 1 teaches providerConfig.include). Rubric lines only; the must_contain tokens stay. Evals are not priced (fix(skills-ratchet): evals/** leave the priced population; the standing 「先削重复,余额按实测提高」 ruling is the gate-recognised raise path #27984).
  4. (carrier: skills(automation): the connector input recipe still says os validate does not judge connectorConfig.input, which PR #28150 makes false #28162, a note on the card) skills(automation): the connector input recipe still says os validate does not judge connectorConfig.input, which PR #28150 makes false #28162's PR must start from main after this PR lands and keep bullet 2's schema sentences; it changes only the os validate and template-token clauses. PR fix(spec,service-automation,lint)!: registration and validate judge a connector_action's connectorConfig.input value slot #28150 itself touches no skills file, so there is no git conflict between fix(spec,service-automation,lint)!: registration and validate judge a connector_action's connectorConfig.input value slot #28150 and this PR.
  5. (carrier: the dev report's next edition, no code) The report's deviation 2 names a phrase the eval does not contain; the stale rubric line is the one in should-fix 3. Recorded here so the seat's ACCEPT does not repeat it.

Contract review 6526392518 must-fix 1: "os validate does not judge it
yet" left its antecedent open, and the open PR for #27968 makes
registration and os validate judge the value-slot envelope (not the
schema fit). All three sites now say os validate does not judge the
input against the action's inputSchema, true in either landing order.

Paid in integration-recipes.md by recipe 1's "holds GetBalance alone"
comment: the comment above it says the document is trimmed to the
operations the app calls, and the flow below calls GetBalance.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016WV4cwp1Wc6nB6ePmS4ePn
…ince #27968

With the #27968 fix on main, registerFlow and os validate refuse a {…}
token (and a malformed or template envelope) in connectorConfig.input
at connectorConfig.input.<key>, so the recipe's "{…}, {{ }} are literal
text" is no longer true. The connector_action row and recipe Holds
bullet 2 now teach the publish-time refusal, that a value from the
record is a CEL envelope, and the run-time inputSchema check that
os validate does not perform yet. Recipe 4 gets its runAs reason back.
Eval 1's rubric names the inputSchema check and drops a clause the
recipe no longer teaches; its must_contain tokens are unchanged.

Paid by same-file restatement cuts: SKILL.md drops the record_change
row's binding aside (the Trigger Types heading names the start node's
config.triggerType), the node-types lead's "e.g. approval" (the requires
table names the plugin), "bare CEL;" in the trigger example (rule 4 and
the CEL blockquote) and "the surface just never runs" (the requires
table's Absent column); the recipe drops the answer bullet's CEL example
(recipe 1 reads the same path), recipe 1's "admin sets" comment (the
intro says the administrator supplies the ref), the "ship it in the
package" clause (the intro says a spec ships in the package) and the
signing bullet's "same handling" (the section heading).

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016WV4cwp1Wc6nB6ePmS4ePn
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:skills#2 · os-elon-musk · session_016WV4cwp1Wc6nB6ePmS4ePn

Round 2 · head e26acddd

This PR now also carries #28162 (claim 6526661954): PR #28150 merged (3cc45cc46), and origin/main is merged into this branch (3c516fee, no conflict).

Must-fix 1 (review 6526392518), commit e7e87755. All three sites name the check: SKILL.md:87 and recipe Holds bullet 2 say "os validate does not judge the inputSchema fit yet", and the connectors.mdx row says "os validate does not judge the input against the inputSchema yet".

#28162, commit e26acddd. SKILL.md:87 and recipe Holds bullet 2 teach main after #28150:

"({…}, {{ }} are literal text)" is gone (it reverses should-fix 1, as the seat asked). Recipe 4 gets its runAs reason back (// no trigger user).

Eval 1 rubric (evals/integrations-declared.json, expected_output only; must_contain unchanged). The two lines the review quotes ("sent as written … waits on the platform", "the openapi provider has no include key") are not on main at 412908cf: git grep over skills/ and ui/ finds neither. The rubric already says the payload is a CEL envelope. Two edits instead: it now adds "judged against the action's inputSchema before dispatch", and it drops "trimming still keeps the package small", which round 1 cut from the recipe. Round 1's deviation 2 named that phrase correctly: it is in eval 1 on main.

New same-file restatement cuts, each with a surviving home:

  • SKILL.md:
    • the record_change row's "(bind via the start node's triggerType)" (the Trigger Types heading names config.triggerType);
    • the node-types lead's ", e.g. approval" (the requires table names approval and its plugin);
    • "bare CEL;" in the trigger example's comment (rule 4 and the CEL blockquote);
    • "; the surface just never runs" (the requires table's Absent column).
  • integration-recipes.md:
    • the answer bullet's example { dialect: 'cel', source: 'bal.body.available[0].amount' } (recipe 1's stripe_available reads the same path);
    • recipe 1's // admin sets STRIPE_SECRET_KEY (the intro says the administrator supplies the ref's value);
    • "and ship it in the package" (the intro: a spec ships in the package);
    • the signing bullet's "same handling," (the section heading).

Tokens. SKILL.md 6457 → 6456 / 6457. integration-recipes.md 2236 → 2229 / 2236. No ceiling moved, and scripts/check-skills-token-ratchet.mjs is untouched.

Gates at e26acddd, after a fresh pnpm install --frozen-lockfile --ignore-scripts and the @objectstack/lint... and @objectstack/client-react... builds: dispatch-gates --commands derives 60 families. 59 exit 0. check:dual-build-cjs-loads exits 3 (NOT MEASURED, needs every dist). --ran reconciles 60 / 59 / 1 / 0, and the derivation re-run at the head is identical. check-commit-card-trailers --range origin/main..HEAD passes on 4 messages.


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:skills#2 · os-elon-musk · session_016WV4d1QkPVVzNz3FJqb2iS

Contract-review-claim: session_016WV4d1QkPVVzNz3FJqb2iS · head e26acdd · 2026-10-30T16:02Z

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:skills#2 · os-elon-musk · session_016WV4d1QkPVVzNz3FJqb2iS

Contract review

Head-sha: e26acddd2af42a9c06c607712735a556996ab8ee
Served-tier: CONTRACT_REVIEW_TIER
Local-runs: probe — the skills ratchet family (node scripts/check-skills-token-ratchet.mjs on the head worktree and on a detached worktree at the merge-base 412908cf, node scripts/pm/check-skill-line-ratchet.mjs, node scripts/pm/check-skill-id-lint.mjs, node scripts/check-skill-identifier-liveness.mjs, node scripts/check-skill-top-level-keys.mjs, node scripts/check-doc-route-spelling.mjs --advisory, pnpm check:doc-anchors, node scripts/check-docs-section-name.mjs, pnpm check:docs-single-h1, pnpm --filter @objectstack/spec run check:skill-docs and check:skill-refs, and node scripts/pm/check-governed-merges.mjs --pr 28170) was executed locally, because the one gate this diff can turn red is a per-file token count held at a headroom of 1 and 7 that no check-run prints as a number; nothing else was built or run.
Scope: skills/objectstack-automation/SKILL.md, skills/objectstack-automation/references/integration-recipes.md, skills/objectstack-automation/evals/integrations-declared.json (the register's three hits, Tier H) + content/docs/automation/connectors.mdx (the cross-domain row, triage 6521031879), packages/services/service-automation/src/builtin/connector-nodes.ts (the #27995 block :126-163 and collectInputSchemaViolations), packages/services/service-automation/src/builtin/connector-input-schema.test.ts (the pins, read not run), packages/services/service-automation/src/builtin/connector-input-registration.test.ts (the #27968 pins, read not run), packages/services/service-automation/src/flow-registration-checks.ts (the connectorConfig locator :596-600), packages/services/service-automation/src/plugin.ts (the boot warn-and-skip :1583), packages/spec/src/automation/flow-value-slot-template.ts (VALUE_SLOT_TEMPLATE_REFUSAL), packages/lint/src/validate-expressions.ts (the os validate door), packages/services/service-automation/src/engine.ts (NodeFailureClass, the runtime default), packages/formula/src/validate.ts (CEL int), scripts/check-skills-token-ratchet.mjs and scripts/pm/check-skill-line-ratchet.mjs (the gates that hold the ceilings); this one PR closes card #28041 (Fixes #28041) and folds card #28162 (claim 6526661954), and both cards' wanted lists are judged here

Inputs: the three-dot diff 412908cf...e26acddd (merge-base 412908cf, 4 files, +41 / −39; four commits on the branch: f2cd1d9, e7e8775, the merge 3c516fe of origin/main 412908cf, and e26acddd2; the three authored commits carry Co-authored-by and Claude-Session, no model name, no Refs); git merge-base --is-ancestor 3cc45cc46 e26acddd is true, so PR #28150's merge is in the head; origin/main had moved to c48cd2c10 at review time; the PR body (head e26acddd, draft, labels documentation, size/s, skip-changeset, auto_merge null) and its comments 6526073574 (round-1 claim), 6526392518 (the round-1 FAIL record on f2cd1d9, this session's), 6527261124 (the dev's round-2 report), 6527290100 (the contract-review claim naming this session and this head); card #28041 (body, triage 6521031879 and 6524854844, claim 6525243871); card #28162 (body, triage 6525897453, carrier note 6526393954, claim 6526661954; open, pm:dispatched, domain:skills); PR #28035 (merged ec7e15abc) and PR #28150 (merged 3cc45cc46 2026-10-30T15:18Z, review 6525595405); #27968 (closed by #28150's merge); eval 1 of integrations-declared.json read with git show at 27e0bd584, f2cd1d9, 412908cf and e26acddd; the code at origin/main for every claim the new sentences make; the head's check-runs (two polls, last at 2026-10-30T16:06Z).

① Derived judgments

  1. Correction of the round-1 record (6526392518), ①.11 and should-fixes 3 and 5: the dev was right, the record was wrong. Read with git show at the base 27e0bd584, at f2cd1d9 and at 412908cf, eval 1's expected_output contains "trimming still keeps the package small" and contains neither "connectorConfig.input is sent as written, so a per-contract payload waits on the platform too" nor "the openapi provider has no include key"; it already said "connectorConfig.input is a value slot: the per-contract payload reads the record through a CEL envelope". The round-1 record read the eval from the main checkout at bacb3e6a0, a stale detached HEAD, not from the base, and reported that tree's older rubric as main's. The dev's round-1 deviation 2 named the phrase correctly, and the carrier note 6526393954's "two stale lines" do not exist on main. The two edits the dev made instead (①.6) are the right ones. Withdrawn: round-1 should-fix 3 (the two quoted lines) and should-fix 5 (the deviation note). Round-1 should-fix 2 (recipe 4's reason) is met at this head; should-fix 1 (keep the {{ }} clause) is reversed by the fold of skills(automation): the connector input recipe still says os validate does not judge connectorConfig.input, which PR #28150 makes false #28162, as the carrier note itself provided; should-fix 4 (base after docs(skills,automation): a connector_action input is judged against the action's inputSchema before dispatch, refused as VALIDATION_ERROR #28170) is moot by the fold.
  2. Accept set: unchanged — correct. Prose only, three governed skill files (SKILL.md, the recipe, the eval fixture) and one docs page. Clause-②: no and Metadata-protocol: none hold. The register now reads 3 of 4 paths as skills/** (the eval joined the surface with skills(automation): the connector input recipe still says os validate does not judge connectorConfig.input, which PR #28150 makes false #28162's claim), Tier H, 80 changed lines under the human-merge threshold.
  3. Must-fix 1 of round 1 — closed (e7e8775). SKILL.md :87 "os validate does not judge the inputSchema fit yet"; recipe Holds bullet 2, last sentence, the same; connectors.mdx row "os validate does not judge the input against the inputSchema yet". All three now name the check, and all three are true on main after fix(spec,service-automation,lint)!: registration and validate judge a connector_action's connectorConfig.input value slot #28150: registerFlow and os validate judge the value slot's envelope and a template token (the 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 ledger entry, both doors), and nothing judges the evaluated input against the action's inputSchema before the run (connector-nodes.ts :138-143 is the only site; PR fix(spec,service-automation,lint)!: registration and validate judge a connector_action's connectorConfig.input value slot #28150's two new test files judge envelope shapes only). The clause is true in either landing order, which was the whole point.
  4. The skills(automation): the connector input recipe still says os validate does not judge connectorConfig.input, which PR #28150 makes false #28162 sentences — true against fix(spec,service-automation,lint)!: registration and validate judge a connector_action's connectorConfig.input value slot #28150's merged code. SKILL.md :87 and the recipe say "registerFlow and os validate refuse a {…} token at connectorConfig.input.KEY" (the file spells the placeholder in angle brackets, as the test does). flow-registration-checks.ts :596-600 locates a sibling-block refusal at nodePath.block.path, which for this entry is connectorConfig.input.KEY; connector-input-registration.test.ts :95-101 pins a bare '{rec.id}' refused with node 'call' (connector_action) connector_action input value at connectorConfig.input.customerId: followed by VALUE_SLOT_TEMPLATE_REFUSAL, and :114-116 pins that a refused flow is not registered; plugin.ts :1583 is the boot path that warns [Automation] failed to register flow and skips it, so "refuse at publish" is what happens; the lint door is packages/lint/src/validate-expressions.ts (fix(spec,service-automation,lint)!: registration and validate judge a connector_action's connectorConfig.input value slot #28150's +7/−2), which os validate runs, pinned in validate-expressions.connector-input.test.ts. The text claims the token case only and does not claim the malformed-envelope or template-envelope cases, which are also refused — a true subset, not a falsehood. "A value from the record is a CEL envelope" is the remedy both doors prescribe and what the executor evaluates (resolveValueSlotMap, connector-nodes.ts :124). The old "({…}, {{ }} are literal text)" and "so a malformed envelope fails at run time" are gone, which skills(automation): the connector input recipe still says os validate does not judge connectorConfig.input, which PR #28150 makes false #28162 asked for.
  5. The skills+docs(automation): after #27995, a connector_action input that breaks the action's inputSchema is refused before dispatch; the skill and the connectors docs page still describe it as unchecked #28041 sentences — unchanged from round 1 and still true. Judged keywords (required, type with nullable, properties, items), "once evaluated ... before dispatch", VALIDATION_ERROR with the runtime default so a fault edge routes it, "nothing sent", null on an optional parameter read as absent (:291), text never converted and the int() cast (:159-161; CEL int in formula/validate.ts :1297; the pinned shape at connector-input-schema.test.ts :208). Round-1 ①.2-①.8 stand; the code at origin/main c48cd2c10 is byte-identical at those lines to the round-1 reading (no commit since the base touches connector-nodes.ts).
  6. Row shape. SKILL.md :87 stays one table row; the order now follows the author's timeline (publish-time refusal, then run-time judgment, then the honest gap), which reads better than round 1's. The recipe's Holds bullet 2 does the same and keeps the cast example. The connectors.mdx row is round 1's with the sharpened clause; two cells, fits the table.
  7. Eval 1 — the two edits are right, must_contain untouched. Added: "judged against the action's inputSchema before dispatch" after the CEL-envelope sentence — true (①.4) and the one thing the rubric lacked. Dropped: "trimming still keeps the package small", the phrase round 1 cut from recipe 1; the rubric still wants a trimmed, packaged document and names providerConfig.include with the mcp allowlist meaning and the fatal non-array case, which recipe 1 :70-72 teaches on main. must_contain and must_not_contain are byte-identical. The eval is measured (1235 → 1240 tokens), not ratcheted (fix(skills-ratchet): evals/** leave the priced population; the standing 「先削重复,余额按实测提高」 ruling is the gate-recognised raise path #27984), and dispatch-gates --commands derives no evals family for this diff.
  8. The new cuts — restatement, every prescription survives. Read on the head:
    • SKILL.md record_change row "(bind via the start node's triggerType)": the Trigger Types heading :360 is "Trigger Types (start-node config.triggerType)" and the example :384 sets it. Kept.
    • SKILL.md node-types lead ", e.g. approval": the requires table :340 names approval / approval_revise (plugin-approvals). Kept.
    • SKILL.md trigger-example comment "bare CEL;": rule 4 :280 "Conditions are bare CEL". Kept.
    • SKILL.md "; the surface just never runs": the requires table's Absent column :336-340 ("flows never execute", "no executor for the node type"). Kept, and more precisely.
    • Recipe answer bullet's example { dialect: 'cel', source: 'bal.body.available[0].amount' }: recipe 1 :57 reads bal.body.available[0].amount / 100.0 into stripe_available. Kept.
    • Recipe 1 "// admin sets STRIPE_SECRET_KEY": the intro :6 "one thing the customer's administrator supplies: the value behind" the ref. Kept.
    • Recipe 1 "and ship it in the package" and "// holds GetBalance alone": the intro :10 "ships in the package", the file name stripe.trimmed.json, the trim comment :39, and the node :54 calling GetBalance. Kept.
    • Recipe signing bullet "same handling,": the section heading :149 names the handling. Kept.
    • Round 1's cuts: unchanged and re-read; each surviving home holds (round-1 ①.10).
    • Recipe 4 regains "// no trigger user" on runAs: 'system' (round-1 should-fix 2).
  9. Ratchets and lint hold on the head. Token ratchet: SKILL.md 6457 → 6456 of 6457 (headroom 1), integration-recipes.md 2236 → 2229 of 2236 (headroom 7), both ceilings unchanged, scripts/check-skills-token-ratchet.mjs not in the diff; the merge-base worktree reads 6457 and 2236, so the dev's numbers are exact. check-skill-line-ratchet exit 0; check-skill-id-lint 105 files clean; check-skill-identifier-liveness OK (486 citations); check-skill-top-level-keys exit 0; check-doc-route-spelling --advisory clean; check:doc-anchors, check-docs-section-name, check:docs-single-h1, check:skill-docs, check:skill-refs all exit 0. Check Documentation Links, Build Docs and Lint · docs & code guards are success on the head.
  10. skills(automation): the connector input recipe still says os validate does not judge connectorConfig.input, which PR #28150 makes false #28162's scope is fully met. Its three files: SKILL.md :88 (now :87) rewritten; recipe :18-21 (now :18-26) rewritten; eval 1 re-read and edited. Its "What changes": both passages teach the rule on main after fix(spec,service-automation,lint)!: registration and validate judge a connector_action's connectorConfig.input value slot #28150 (value slots judged at publish, a template token refused at connectorConfig.input.KEY, a record value as a CEL envelope). "Run the skill's evals afterwards": no gate derives them and the dev reports none run; the rubric and tokens were read instead (①.6) — noted, not owed by a gate.
  11. PR mechanics (the coordinator's question). The body carries Fixes #28041 on its own line and no other closing keyword; skills(automation): the connector input recipe still says os validate does not judge connectorConfig.input, which PR #28150 makes false #28162 is not mentioned in the body at all, so no keyword sits beside it and the merge will not close it. That is a valid shape: review-checklist.md says Fixes only when the merge should close the card and that a hand-closed card's arrangement is written in a comment. The seat closes skills(automation): the connector input recipe still says os validate does not judge connectorConfig.input, which PR #28150 makes false #28162 by hand at landing with a comment citing this PR and this record, and removes pm:dispatched (landing细则 B). No closing keyword is needed elsewhere. One loose end: claim 6526661954 says "PR docs(skills,automation): a connector_action input is judged against the action's inputSchema before dispatch, refused as VALIDATION_ERROR #28170 will carry Fixes #28041 and Fixes #28162", which the body does not; the seat's hand-close comment should say the keyword was deliberately left out (should-fix 1).
  12. Consistency elsewhere. git grep on origin/main finds no third sentence under skills/**, content/docs/** or docs/adr/** that calls the input unchecked or unjudged; fix(spec,service-automation,lint)!: registration and validate judge a connector_action's connectorConfig.input value slot #28150's own prose (flow.zod.ts describe text, references/automation/flow.mdx :150, the engine.ts docblock) now agrees with the skill: a literal is handed on as written, an envelope is evaluated, a template token is refused at registration or validation.

② Semver level

No release. skip-changeset is right: no published package ships skills/** or content/docs/**; dispatch-gates derived no changeset family; Check Changeset is skipped on the head, the skip-changeset label path. Clause-②: no is right; the narrowings this text documents (PR #28035, PR #28150) carried their own declarations and changesets.

③ Boundary flags

  • Dev flags: no open_questions. The round-2 report (6527261124) disputes round-1 should-fix 3 — settled in the dev's favour (①.0). check:dual-build-cjs-loads exit 3 NOT MEASURED again: immaterial to a prose diff and hosted by Build Core, success on the head.
  • Merge instead of rebase: 3c516fe merges origin/main 412908cf with no conflict; the three-dot diff against the merge-base is the four files above and nothing else; the trailers check passes on all four messages per the dev, and the three authored commits were read here (no model name, no Refs).
  • Independence: the diff was produced by session_016WV4cwp1Wc6nB6ePmS4ePn on claude/project-thread-bcip5d; this record is rendered by session_016WV4d1QkPVVzNz3FJqb2iS, which did not draft it. Claim 6527290100 names this session and this head; no competing claim, hold or hand-off; no reviews on the PR.
  • Author: objectstack-fleet[bot]; no non-bot login to record.
  • Tier: H by the register (skills/** ×3); the maintainer or a GOVERNED_APPROVERS review lands it. Draft; auto_merge null; nothing to disarm.
  • CI (43 check-runs on the head, last poll 2026-10-30T16:09Z): 29 success, 13 skipped by path or design, 0 failure, 1 in progress (Test Core (1/8)). Both required jobs are success: Lint & Repo Gates (with Lint · repo & tooling gates, Lint · ESLint, Lint · docs & code guards, Lint · PM dispatch-gates, Lint · CI, release & engine gates, the three Lint · scoped jobs) and TypeScript Type Check (with its four Type Check · lanes). Also success: Build Core, Build Docs, Test Core (2/8), (3/8), Test UI, Plan Test Core shards, PR-body guards, Governed Surface Queue Guard, Dogfood Regression Gate, Check PR Size, Check Documentation Links, Auto Label, Spec property liveness, Live E2E UI, filter. Check Changeset is skipped on the head (the skip-changeset label path). The landing seat re-reads the one in-progress shard before the ready flip.
  • Commit subjects: e26acddd2's subject reads "... judged at publish since 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" — a plain reference, not a closing keyword and not a Refs trailer; the dev reports check-commit-card-trailers --range origin/main..HEAD passing on all four messages, and PR-body guards is success. Noted, not a finding.
  • Not re-run here: the dev's 60 dispatch-gates families (read from the report); the two service-automation suites (pins read, not executed).

④ Design judgment

Rules face, the three skill files, against the code they cite and the scenario they are accepted against (an AI author wiring a connector_action whose input reads the record and must satisfy an OpenAPI action's schema):

Implemented-by: claude/project-thread-bcip5d
Reviewed-by: session_016WV4d1QkPVVzNz3FJqb2iS

VERDICT: PASS

Must-fix: none.

Should-fix:

  1. (carrier: the seat's hand-close comment on skills(automation): the connector input recipe still says os validate does not judge connectorConfig.input, which PR #28150 makes false #28162 at landing, no code) Say there that Fixes #28162 was deliberately left off the PR body (claim 6526661954 said it would be carried) and that the merge of PR docs(skills,automation): a connector_action input is judged against the action's inputSchema before dispatch, refused as VALIDATION_ERROR #28170 at e26acddd is the delivery; remove pm:dispatched in the same stroke.
  2. (carrier: the round-1 record 6526392518, no code) This record supersedes its ①.11 and its should-fixes 3 and 5 (①.0 above); the seat's ACCEPT should cite this record, not round 1's, for the eval finding.
  3. (carrier: the next SKILL.md editor, no card) SKILL.md ends 1 token under its ceiling and the recipe 7 under; the ratchet is shrink-only, so the next edit that touches scripts/check-skills-token-ratchet.mjs may lower both pins.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:skills#2 · os-elon-musk · session_016WV4d1QkPVVzNz3FJqb2iS

维护者速读

席位意见:ACCEPT。契约复核分两轮:

首轮记录里关于 eval 的两条 should-fix(3 和 5)不成立:复核员读的是一个过时的本地 HEAD。record2 ①.0 已经撤回,dev 对 eval 的改法是对的。#28162 上的载体说明已据此更正。

席位核对

os-elon-musk pushed a commit that referenced this pull request Oct 31, 2026
…ypes text, and the two skills changesets PR #28170 and PR #28290 missed

A `skills/**` change ships in `@objectstack/skills`, so it owes a patch
changeset, never `skip-changeset` (contract review 6539232473, must-fix 1).
PR #28170 and PR #28290 landed skill text under the same mistaken reading;
their entries are carried here.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016WV4d156vwPo83g9GQuJSt
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation needs-user-decision size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

3 participants