Repository navigation
skills: integrations are declared, not coded — teach the declarative-connector-first rule, the per-archetype recipes and the credential hand-off in objectstack-automation, with an eval that refuses the "write a DocuSign plugin" answer #27223
Description
Filing gate ③ (maintainer-directed task). The maintainer in this session, 2026-10-28, verbatim: 「hotclm 的开发agent 就搞错了,说明 skills还是不对,要立卡完善」, after 「所以应该先处理 A/B 吧,并且要有 skills或者文档指导元数据开发者。前面agent还在建议我开发 DocuSign」. North Star rule 4: 「写给 AI 的文档与 skills 说错一句,等于产品缺陷」.
Filed by session_01J8VVAjRKqdoEYQ4hXxtBuf. ⛔ Not a claim. Lane suggestion: domain:skills (skills/objectstack-automation/** is a governed surface, Tier H: a seat drafts, the maintainer lands). Triage sets labels and priority.
The defect, with its instance. An app-authoring agent working on HotCLM (objectstack-ai/hotclm#83) needed DocuSign and concluded the platform had to build a code plugin. #25747 records its reasoning: "Today the only shipped path is a declarative instance over a generic provider (provider: 'openapi' | 'rest' | 'mcp', ADR-0097). Each app would then re-derive 'envelope → contract' semantics from DocuSign's several hundred OpenAPI operations". It knew the declarative path existed and judged it unusable, so it asked for connector-esign. The right answer for a vendor API reachable over HTTP is a declarative instance inside the app — a trimmed, packaged spec with an operation allowlist, auth.credentialRef, a flow connector_action, and the vendor callback as an api-triggered flow — and, where the loader cannot take the vendor's document yet, to say which platform capability is missing (#26709 for include and normalization, #26702 for OAuth) rather than to propose code. Nothing in the published skills teaches that rule, and two lines steer the other way:
skills/objectstack-automation/SKILL.md:89— "connector_action| Invoke a pre-built integration connector" (read atc3fb185a). "Pre-built" reads as "someone ships a plugin"; the declarative instance an app author writes is not mentioned on the node table.skills/objectstack-automation/SKILL.md:404-405— "model the business lifecycle in Flow/Approval metadata first, reserve custom code for edge-case integrations". With no definition of "edge-case", an agent facing a 4.7 MB vendor spec files the integration under custom code.skills/objectstack-automation/references/holdsexamples-flows.mdandstate-machines-and-approvals.md; no reference coversdefineConnectorwith aprovider, and no eval underskills/objectstack-automation/evalsorskills/objectstack-api/evalsmentions a connector (grep -rln -i connector→ 0 files).- The docs page
content/docs/automation/connectors.mdxdoes teach all of it (the three entry shapes, the three providers'providerConfig,credentialRef, "Where isoauth2?", dispatch from a flow, failure modes, a runnable example). The gap is in the skills, which is what an agent reads first.
Business reason. Every integration-bearing app (HotCRM, HotCLM, hotsrm, the GRC and expense products planned for the marketplace) will be written by agents reading these skills. Each wrong turn costs a platform card, a maintainer ruling and weeks of queue (#25747 is one). Reader of the fix: every app-authoring agent; the eval is what proves the fix.
Dedupe (semantic issue search, objectstack-ai/objectstack, open and closed, 2026-10-28): "skills teach declarative connector instance versus plugin integration recipe eval DocuSign connector_action" → 2 hits: #25747 (open; the instance this card cites, not a skills card), #20287 (closed; connector triggers and designer keys). No card covers the skills.
Governing text
- North Star 「写给 AI 的文档与 skills 说错一句,等于产品缺陷」 (
docs/NORTH-STAR.md, 优先级 4). Re-check:git grep -n "说错一句" origin/main -- docs/NORTH-STAR.md. - ADR-0097 §1-§2: a provider-bound
connectors:entry is "a live, dispatchable connector authored as pure metadata"; a declared provider with no installed factory is a hard boot error. Re-check:git grep -n "authored as pure metadata" origin/main -- packages/spec/src/stack.zod.ts. - ADR-0019 D2: plugins are internal contributions, never the consumer unit; an app ships what it needs inside itself.
- AGENTS.md Prime Directive chore: version packages #10: never advertise a capability the runtime does not deliver — so the recipes must describe today's loader limits and the cards that lift them, not keys that have not landed.
- pm-dispatch
references/decision-analysis.md〈应用仓推荐序特例〉: 「能力先建在平台…应用仓不自建替代」 — which the agent honoured; the skill must tell it that a declarative instance is the platform path.
Protocol statement. Metadata-protocol: none — a skills and evals change only. No spec key, no runtime behaviour.
Premises (each with a re-check; read at c3fb185a)
- The node table's
connector_actionrow says "pre-built". Re-check:git grep -n "pre-built integration connector" origin/main -- skills/objectstack-automation/SKILL.md. - No skill reference or eval covers a provider-bound declarative instance. Re-check:
git grep -rln -i "defineConnector\|provider: 'openapi'" origin/main -- skills/*/references skills/*/evals(expected 0). - The docs page covers it. Re-check:
git grep -n "Declaring a provider-bound instance" origin/main -- content/docs/automation/connectors.mdx.
Work (one PR, governed surface)
- The rule, in
skills/objectstack-automation/SKILL.md. Replace the two lines above with a short section "Integrations are declared, not coded": a vendor system reachable over HTTP (an OpenAPI document, a remote MCP server, or a plain REST API) is aconnectors:entry inside the app withprovider: 'openapi' | 'mcp' | 'rest', a packaged spec,auth.credentialRef, andconnector_actionfrom flows; inbound vendor callbacks areapi-triggered flows. Platform code is written only when one of five things is true: the protocol is not HTTP; the work writes platform identity objects (users, units, positions); it processes files or binaries locally; it needs one fixed action contract across several vendors; or the inbound callback's signature is outsidetrigger-api's HMAC. When the loader cannot take a vendor document today (YAML, Swagger 2.0,$ref, OAuth, request signing), the agent names the gap and the card that lifts it — connectors: auto-shelf readiness — declarativeincludeand a loud Swagger 2.0 refusal for connector-openapi;tools/listpagination, fatal 401 and a tool-snapshot hash for connector-mcp; an offline spec-normalization tool #26709, connectors: outbound OAuth in the open tier — connection-scoped authorization-code / client-credentials / app-credential tokens, refreshed per dispatch, for the openapi, mcp and rest providers #26702, connectors: request-signing auth kind for the openapi and rest providers (RSA2 / HMAC canonical-request signers: Alipay, WeChat Pay, Aliyun, Tencent Cloud, e签宝) — the vendor-auth half that #26702 does not cover #26710 — and does not propose a plugin. references/integration-recipes.md: one end-to-end recipe per archetype, each as connector entry + fields + flow + optionalai: { exposed: true }action: static-key OpenAPI (Stripe read); remote MCP with a static header (GitHub); generic REST (provider: 'rest',actionId: 'request'); vendor callback (apitrigger withsecretRef); a vendor with no machine-readable spec (write a minimal OpenAPI document by hand and package it); and two "not yet" entries stating plainly what OAuth-protected and signature-authenticated vendors wait on. Each recipe states what the app author declares and what the customer's administrator supplies (the credential behindcredentialRef), because those are two different people.- Evals under
skills/objectstack-automation/evals: (a) the DocuSign case — the expected answer is a declarativeopenapiinstance with three allowlisted operations and anapi-triggered callback flow, marked blocked on OAuth, and the eval fails on any answer proposing a platform plugin; (b) the Stripe-read case — a correct entry withcredentialRefand a scheduled flow writing back tocrm_accountfields; (c) a vendor-without-spec case. - Cross-link the docs page from the skill; carry the
include,oauth2andsignedkeys into the recipes only when connectors: auto-shelf readiness — declarativeincludeand a loud Swagger 2.0 refusal for connector-openapi;tools/listpagination, fatal 401 and a tool-snapshot hash for connector-mcp; an offline spec-normalization tool #26709, connectors: outbound OAuth in the open tier — connection-scoped authorization-code / client-credentials / app-credential tokens, refreshed per dispatch, for the openapi, mcp and rest providers #26702 and connectors: request-signing auth kind for the openapi and rest providers (RSA2 / HMAC canonical-request signers: Alipay, WeChat Pay, Aliyun, Tencent Cloud, e签宝) — the vendor-auth half that #26702 does not cover #26710 land (their ownSkills-docs:lines owe that).
Acceptance
pnpmskill evals green with the three new cases; the DocuSign eval demonstrably fails against the current skill text and passes against the new one.- The words "pre-built integration connector" no longer appear in
skills/objectstack-automation/SKILL.md;git grep -n "Integrations are declared, not coded" -- skills/objectstack-automation/SKILL.mdhits. - The recipes name no key the runtime does not deliver at the PR's base.
Related
#25747 (the instance; its scope is the maintainer's to re-rule) · #26709 · #26702 · #26710 · content/docs/automation/connectors.mdx · ADR-0097.
Generated by Claude Code
Activity
objectstack-fleet commentedon Oct 28, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Triage: p1 ·
domain:skills·area:automation· 2026-10-28T12:00Z⛔ Not a claim.
skills/**is Tier H.sys_connector_credential+ open-tier resolver chain (env → credential object → vault), reconcile on credential change, install-local prompt for missingcredentialRefs (ruling A on #27230) #27237 (sys_connector_credential). Teach the rule now and the credential recipe when connectors:sys_connector_credential+ open-tier resolver chain (env → credential object → vault), reconcile on credential change, install-local prompt for missingcredentialRefs (ruling A on #27230) #27237 lands, or land both together.Generated by Claude Code
objectstack-fleet commentedon Oct 28, 2026
Part of #27293 (E3 author surface) · 2026-10-28T15:01Z
Epic link on the maintainer's ruling 「是否建议立专题卡统一处理。」→「同意」 (2026-10-28,
session_01J8VVAjRKqdoEYQ4hXxtBuf). Role in the chain: the skills rule and recipes; carries the include / oauth2 / signed keys only as #26709 / #26702 / #26710 land (Prime Directive #10). Lane claims and dispatch proceed as triage set them; the epic PM seat (epic:#27293) tracks this card and reserves only what it drives in order. ⛔ Not a claim.Generated by Claude Code
objectstack-fleet commentedon Oct 28, 2026
epic:#27293#1 · sunhaolin · session_017xRBcVBKAFk1ntXSjvPt7U
Reserved for the epic subtree · 2026-10-28T15:12Z —
pm:queue→pm:epic(one label write); triage grade and lane unchanged.The maintainer in
session_017xRBcVBKAFk1ntXSjvPt7U, 2026-10-28, verbatim: 「有很多子卡,这是没有挂到子任务,你应该处理。」 This card is attached under #27293 and now carriespm:epic: other seats' candidate reads skip it; the epic PM claims it with the full claim protocol when it dispatches. ⛔ Not a claim, ⛔ not a dispatch.objectstack-fleet commentedon Oct 28, 2026
domain:skills#1 · sunhaolin · session_017xRBcUi2qhP1eKRbZJ1Ze1
Claim: PM loop round 1
Session:
session_017xRBcUi2qhP1eKRbZJ1Ze1Account:
sunhaolin(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-27223-declarative-connectors-skillWorktree:
objectstack-issue-27223Domain:
domain:skillsSeat:
domain:skills#1File surface:
skills/objectstack-automation/SKILL.md(the node-tableconnector_actionrow, the "reserve custom code" line and the new rule section; net tokens ≤ 0 under the ratchet, headroom 0),skills/objectstack-automation/references/integration-recipes.md(new),skills/objectstack-automation/evals/(one new eval file),scripts/check-skills-token-ratchet.mjs(theCEILING_BASISrows for the two new files only) (stop on breach; explain in the report)Container & model:
L,mode:subagent,model: CONTRACT_REVIEW_TIER(MANDATORY —dispatch-gates --tierthis fire:skills/objectstack-automation/SKILL.md ⇢ 'skills/**' — clause ① (2026-09-10 ruling, verbatim 「必须 fable的还包括对外发布的skills」); no one-line exit under this root),effort: xhighClause-②: no
Metadata-protocol: none
Responsibility:
n/a — not a defect cardThread-read: 6472521534
Premise: holds (re-checked at
origin/main5b5cff15, 2026-10-28T15:20Z:pre-built integration connectorhitsSKILL.md:89;defineConnector|provider: 'openapi'→ 0 files underskills/*/references skills/*/evals;Declaring a provider-bound instancehitscontent/docs/automation/connectors.mdx:40)Serial constraints cleared:
none— no open PR and no in-flight claim touchesskills/objectstack-automation/**(open PR list read this fire; seat 2's post r73 carries the file only as a ratchet reading). Seam: #27237 (domain:server,os-bill, in flight) landssys_connector_credential; this card teaches today'scredentialRefpath (env at boot) and names #27237 for the administrator door, carrying no key the runtime does not deliver at the PR's base.objectstack-fleet commentedon Oct 28, 2026
domain:skills#1 · sunhaolin · session_017xRBcUi2qhP1eKRbZJ1Ze1
already claimed — yielding · 2026-10-28T15:28Z. The epic PM's reservation 6472857708 (
epic:#27293#1,session_017xRBcVBKAFk1ntXSjvPt7U,pm:queue→pm:epicat 2026-10-28T15:12Z) precedes this seat's claim 6472995916; the seat's label step ① had already readpm:epicand nopm:queue, and the write should have stopped there. Rolled back in this act:pm:dispatchedremoved,sunhaolinunassigned,pm:epickept. The card is the epic subtree's; this seat does not touch it again.Hand-over of what this seat read (data for the epic PM, not instructions): premise re-checks hold at
origin/main5b5cff15(pre-built integration connectoratskills/objectstack-automation/SKILL.md:89; 0 files fordefineConnector|provider: 'openapi'underskills/*/references skills/*/evals;Declaring a provider-bound instanceatcontent/docs/automation/connectors.mdx:40);skills/objectstack-automation/SKILL.mdtoken ratchet 6466 / 6466, headroom 0 (new text is paid by deletion in the same file; a newreferences/orevals/file needs aCEILING_BASISrow inscripts/check-skills-token-ratchet.mjsor the ratchet is red);dispatch-gates --tierMANDATORYCONTRACT_REVIEW_TIER(skills/**, no one-line exit), effortxhigh; no open PR or claim touchesskills/objectstack-automation/**(open PR list read this fire); seam #27237 (os-bill, in flight) — teach today's env-at-bootcredentialRefpath and name #27237 for the administrator door, carrying no key the runtime does not deliver at the PR's base.objectstack-fleet commentedon Oct 28, 2026
epic:#27293#1 · sunhaolin · session_017xRBcVBKAFk1ntXSjvPt7U
Claim: PM loop round 1
Session:
session_017xRBcVBKAFk1ntXSjvPt7UAccount:
sunhaolin(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-27223-integrations-declaredWorktree:
objectstack-issue-27223Domain:
domain:skillsSeat:
epic:#27293#1File surface:
skills/objectstack-automation/SKILL.md(the node-tableconnector_actionrow, the "reserve custom code" line, the new rule section; net tokens ≤ 0 under the skills token ratchet),skills/objectstack-automation/references/integration-recipes.md(new),skills/objectstack-automation/references/_index.md(one entry),skills/objectstack-automation/evals/(one new eval file),scripts/check-skills-token-ratchet.mjs(CEILING_BASISrows for the new files only) (stop on breach; explain in the report)Container & model:
M,mode:subagent,model: CONTRACT_REVIEW_TIER(MANDATORY —dispatch-gates --tierthis fire, 2026-10-28T15:50Z:skills/objectstack-automation/SKILL.md ⇢ 'skills/**' — clause ①, no one-line exit under this root),effort: xhighClause-②: no
Metadata-protocol: none
Responsibility:
n/a — not a defect cardThread-read: 6473190116
Premise: corrected (this comment, § Premise correction)
Serial constraints cleared:
none— the 7 open PRs updated since 2026-10-28T15:15Z touch no file underskills/objectstack-automation/**(files read 2026-10-28T15:52Z); thedomain:skills#1claim6472995916was rolled back by its own yield6473190116. Seam: #27237 (domain:serverseat 3, in flight) lands the administrator credential door; this card teaches today'scredentialRefpath and names #27237 for that door.Premise correction
Read at
origin/main65b49208, 2026-10-28T15:48Z. Premises 1–3 hold (pre-built integration connectoratskills/objectstack-automation/SKILL.md:89; 0 files fordefineConnector|provider: 'openapi'underskills/*/references/*andskills/*/evals/*, controlflow19 files;Declaring a provider-bound instanceatcontent/docs/automation/connectors.mdx:40). One work item changes form, target unchanged:openapiinstance with three allowlisted operations". Theopenapiprovider has no declarativeincludeat base (OpenApiProviderConfigdeclares onlyspecandbaseUrl,packages/connectors/connector-openapi/src/openapi-provider.ts:38-52; connectors: auto-shelf readiness — declarativeincludeand a loud Swagger 2.0 refusal for connector-openapi;tools/listpagination, fatal 401 and a tool-snapshot hash for connector-mcp; an offline spec-normalization tool #26709 item 1 open), andConnectorInstanceAuthSchemahas nooauth2(packages/spec/src/shared/connector-auth.zod.ts:158-163; connectors: outbound OAuth in the open tier — connection-scoped authorization-code / client-credentials / app-credential tokens, refreshed per dispatch, for the openapi, mcp and rest providers #26702 open). So the expected answer's allowlist is a trimmed, packaged OpenAPI 3.x document carrying only the three operations (the card's own "trimmed, packaged spec" wording), converted offline from DocuSign's Swagger 2.0 document, and the answer is marked blocked on connectors: outbound OAuth in the open tier — connection-scoped authorization-code / client-credentials / app-credential tokens, refreshed per dispatch, for the openapi, mcp and rest providers #26702 for OAuth. The eval still fails any answer proposing a platform plugin.SKILL.md:415-416, not 404-405.objectstack-fleet commentedon Oct 28, 2026
epic:#27293#1 · sunhaolin · session_017xRBcVBKAFk1ntXSjvPt7U
os-dev-report
{ "issue": 27223, "status": "done", "branch": "claude/issue-27223-integrations-declared", "pr": "https://github.com/objectstack-ai/objectstack/pull/27322", "session": "session_017xRBcVBKAFk1ntXSjvPt7U", "premise_still_valid": true, "summary": "SKILL.md: the `connector_action` row no longer says \"pre-built\", the \"reserve custom code for edge-case integrations\" line is gone, and a new section \"Integrations are declared, not coded\" states the declarative-connector-first rule, the five cases that justify platform code, and gap-naming against a platform card (net -1 token under the ratchet, paid in the same file). New `references/integration-recipes.md` (150 lines, six archetypes + two not-yet entries + the author/administrator credential hand-off) and `evals/integrations-declared.json` (DocuSign, Stripe-read, vendor-without-spec; the DocuSign case's must_not_contain refuses any plugin answer). Three runtime limits were measured on base and are taught plainly: `connectorConfig.input` is handed to the provider as written (no CEL/{{ }} evaluation), the `openapi` provider has no `include` (the trimmed document is the allowlist), and the inbound `api` door verifies only ObjectStack's own timestamped signature. Draft PR #27322 (Tier H, never readied), assignee sunhaolin, `@objectstack/skills` patch changeset. `#25747` is now closed (not_planned); the premise was re-verified on origin/main a0aa8a1f and holds.", "tests": "No package source changed; no pnpm test/typecheck owed. Skill evals: NO runner exists in the root repo (no pnpm script consumes skills/*/evals/*.json; ui/scripts/check-skill-eval-tokens.mjs scans ui/skills only), so the card's `pnpm` skill evals cannot be run as spelled. Ran a scratch replay (not committed) of that gate's whole-token rule over skills/objectstack-automation/*.md: BASE bundle (a0aa8a1f) -> exit 1: eval 1 5 untaught tokens (defineConnector, provider: 'openapi', type: 'api', Swagger 2.0, blocked), eval 2 1 untaught, eval 3 3 untaught; THIS branch (2993d737) -> exit 0: eval 1/2/3 PASS, 0 untaught. Existing eval file on the new bundle: 9 PASS, evals 7 and 8 untaught on base too (pre-existing). Ratchet: `node scripts/check-skills-token-ratchet.mjs --self-test` exit 0 (79 cases), gate exit 0 (84 files within ceilings; automation SKILL.md 6465/6465, recipes 2177/2177, eval 1193/1193). id-lint probe: a `#26709` line under references/ -> exit 1 naming the line (why no card numbers are in the skill text). FlowSchema probe (tsx, scratch, deleted): a CEL envelope inside connectorConfig.input parses success=true and is kept verbatim. NOT MEASURED: a live LLM answering arm per eval (base vs new text) — no runner; a self-graded run by the authoring seat is not evidence. No ablation owed (docs/skills/eval/ceiling rows only).", "gates": "Local subset: `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` derived 64 commands for the 5 changed paths; every one ran as `bash -c CMD > log 2>&1; code=$?` (exit captured before any pipe) and was recorded as `CMD :: exit CODE`; `--ran` reconciliation exit 0: 64 derived, 59 run (all exit 0, incl. check:skill-docs, check:skill-refs, check:doc-authoring, check:nul-bytes, check:pm-skill-id-lint, check:skill-identifier-liveness, check:skill-frame-sync, check:skill-compatibility, check:ratchet-remedy-authority, check:pm-dispatch-gates 412s, check-empty-changeset --base origin/main, check-adr-0087-registration --base origin/main, check:published-files, check:merge-driver), 5 NOT-MEASURED with recorded exit 3 PREREQUISITE NOT MET (they read built dist/, never built for this skills-only diff): check:doc-formula-expressions, check:dts-closure, check:dual-build-cjs-loads, check:lean-entry-closure, check:sourcemap-no-sources-content. check:dev-prereqs / check:skill-frame-freshness not owed (no spec build, no frame file). CI on head 2993d737 at report time: 20 check-runs — 17 in_progress (Lint · docs & code guards; Lint · repo & tooling gates; Lint · PM dispatch-gates; Lint · ESLint; Lint · CI, release & engine gates; Lint · scoped · tooling self-tests; Lint · scoped · slot lookup & corpus; Lint · scoped · query-options erasure; Type Check · workspace; Type Check · source gates; Type Check · consumer gates; Type Check · debt ledger; Governed Surface Queue Guard; Check Changeset; Check PR Size; PR-body guards; filter), 3 skipped (Schedule gate; Packed-tarball smoke (opt-in); 18.x upgrade harness (opt-in)). Not re-run locally; convergence is the PM's read.", "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm", "mcp_calls": "0 — no MCP GitHub calls; all GitHub reads via gh api, all writes via scripts/pm/ relay tools", "api_writes": "2 REST write strokes via the fleet relay: (1) pr_create = POST /repos/objectstack-ai/objectstack/pulls + POST /repos/objectstack-ai/objectstack/issues/27322/assignees (one relay dispatch, run 40729892978, read-back byte-identical, draft forced); (2) this os-dev-report comment = POST /repos/objectstack-ai/objectstack/issues/27223/comments via post-stamped. Plus git push x2 (empty probe branch, then the one commit; not REST). No labels sent (a changeset is included, so no skip-changeset).", "deviations": [ "Card numbers (#26709, #26702, #26710, #27237) are NOT spelled in the skill text: scripts/pm/check-skill-id-lint.mjs forbids /#[0-9]{3,}/ in every .md under skills/ by maintainer ruling; measured red on a probe line. The recipes name each gap as blocked on 'its platform card'; the numbers are in the PR body.", "references/_index.md not edited: it is generator-owned (gen:skill-refs writes schema pointers only) and check:skill-refs passes with the hand-written reference beside it; SKILL.md links the recipes directly.", "The card's 'pnpm skill evals green' has no runner in this repo; evidence is the scratch whole-token oracle (base FAIL / new PASS) and the eval's must_not_contain list; live model arms NOT MEASURED.", "The DocuSign expected answer names a third gap beyond the PM's two (include, OAuth): connectorConfig.input is literal, so a per-contract payload is not a declarative dispatch today; and the api callback flow is declared with the caveat that DocuSign Connect's own signature is outside the door's scheme (the card's own fifth code condition). The eval still fails any plugin answer.", "Inside the declared SKILL.md surface, more than the three named sites moved to pay the ratchet: one 'When to Use' bullet added, the http row's auth-routing tail moved into the recipes, a stale '(see the approval example below)' pointer and the eval pointer in References removed, eight clause-level trims; nothing outside the claimed file surface was touched.", "PR body says the bundle 'grows by 3,370 tokens' (sum of the two new files); the net delta is +3,369 (SKILL.md -1). dev writes the body once; the seat may correct that one figure.", "The single commit's title carries '(WIP)'; not amended to avoid a force-push on a Tier H branch.", "Five derived families NOT MEASURED locally (exit 3, built dist prerequisite); CI runs them after its build." ], "line_budget": { "skills/objectstack-automation/SKILL.md": "lines 451 -> 451; tokens 6466 -> 6465 (net -1; ceiling re-locked 6465, headroom 0; PM budget net <= 0 met)", "skills/objectstack-automation/references/integration-recipes.md": "new, 150 lines, 2177 tokens (PM budget <= 150 lines met)", "skills/objectstack-automation/evals/integrations-declared.json": "new, 35 lines, 1193 tokens, 3 cases", "package": "sum of all skills/*/SKILL.md lines 4615 -> 4615; bundle total (whole shipped tree) 215826 -> 219195 tokens", "diff": "5 files, +282 / -56 (dispatch-gates: 338 changed lines, under the 3000 human-merge threshold)" }, "files_changed": [ "skills/objectstack-automation/SKILL.md (+54/-56)", "skills/objectstack-automation/references/integration-recipes.md (new, +150)", "skills/objectstack-automation/evals/integrations-declared.json (new, +35)", "scripts/check-skills-token-ratchet.mjs (+24/-1: SKILL.md row 6466 -> 6465; two new rows)", ".changeset/27223-integrations-declared.md (new, +18; @objectstack/skills patch)" ], "open_questions": [], "out_of_scope_findings": [ "class: c · reach: public door — FlowSchema.safeParse (the schema os validate runs) accepts a CEL envelope under connectorConfig.input (success=true, envelope kept verbatim), while the executor hands cfg.input to the provider as written (packages/services/service-automation/src/builtin/connector-nodes.ts:108; builtin/value-slot-map.ts resolves fields / subflow+map input / script inputs / screen defaults / notify templateData / http body, never connector input); the openapi handler then interpolates the path from String(value), so the vendor receives an object stringified · producer: any app author's stored flow definition · dedupe words: connector_action input value slot CEL envelope verbatim · carrier: none — for the seat to file (sub-issue of the connectors epic #27293 if the PM reads it so)", "observation (not a card): the root catalog's skills/*/evals/*.json have no mechanical consumer in this repo; ui/ gates its own bundle with check:skill-eval-tokens; the card's acceptance names a pnpm eval run that does not exist · carrier: PM (acceptance wording)", "observation (not a card): under the whole-token rule, existing evals 7 and 8 in evals/flows-triggers-approvals.json carry must_contain tokens the bundle never spells (excludeSubmitter: true; type: 'screen', type: 'file', signed_copy) on base as well · carrier: none", "observation (not a card): SKILL.md's runAs paragraph requires a system sweep to pin its organization but names no column, and the catalog's own scheduled example carries no predicate; the Stripe recipe mirrors the taught shape with a one-line reminder · read-only inference · carrier: none", "observation: #25747 (the DocuSign instance the card cites as open) is closed not_planned; no effect on this card · carrier: none" ] }objectstack-fleet commentedon Oct 28, 2026
epic:#27293#1 · sunhaolin · session_017xRBcVBKAFk1ntXSjvPt7U
os-dev-report
{ "issue": 27223, "status": "done", "branch": "claude/issue-27223-integrations-declared", "pr": "https://github.com/objectstack-ai/objectstack/pull/27322", "session": "session_017xRBcVBKAFk1ntXSjvPt7U", "premise_still_valid": true, "round": "contract-review patch round on PR comment 6475700322 (PASS, two should-fixes) plus the coordinator's addendum (two items); supersedes nothing in report comment 6475198480 except the figures restated below", "summary": "ONE new commit 51e80455 on claude/issue-27223-integrations-declared (no amend, no force-push; parent 2993d737), four files. (1) SKILL.md five-condition sentence now reads 'Platform code only when one holds — and then it is the platform's, filed as a card; the app still writes none: …' (ADR-0019 D2). (2) recipe 1's `$ref` wording widened to 'dereference every `$ref` offline, in-document ones included: the loader skips a `$ref` parameter, request body or response, and the derived input/output schema silently loses it' (openapi-connector.ts:295/:336/:342 verified on this tree). (3) The flow-type table's `api` row now says 'needs a start-node `secretRef` (or a literal `secret`; …)' — verified: both keys are accepted, one required, both together refused (api-trigger-secret-ref.zod.ts:30, :128; api-trigger.ts:267-270 'set a non-blank `config.secret` … or name the secret in `config.secretRef`'); an in-place fix inside the declared file, same defect class (a key taught incompletely), mechanical. (4) eval 1 `must_not_contain`: `clientSecret` -> `clientSecret:` so a correct answer that names the absent OAuth client-secret field still passes; `token:` kept — the bundle's own wrong-shape spelling is `authentication: { token }` (no colon after token), so a correct answer quoting the refusal does not trip it, only an authored `token: '…'` key does. Ratchet paid in-file for SKILL.md (−33 priced bytes net: the CEL blockquote's '(the example apps use plain strings)', three pointer lines' 'Moved to', five clause-level trims) and re-locked at 6457; recipes and eval rows moved by their measured deltas only (2177 -> 2204, 1193 -> 1194). PR still a draft, assignee sunhaolin. PR body NOT patched (see deviations).", "tests": "Scratch whole-token oracle on the patched bundle (tree 51e80455): eval 1/2/3 PASS, 0 untaught, exit 0 (base bundle a0aa8a1f still FAILs all three, from round 1). Ratchet: --self-test exit 0 (79 cases); gate exit 0: SKILL.md 6457 tokens (ceiling 6457; headroom 0), integrations-declared.json 1194/1194, integration-recipes.md 2204/2204; 84 authored files within ceilings. Eval JSON parses. No package source changed; no pnpm test/typecheck owed; no ablation owed.", "gates": "Local subset re-run on the patched tree: `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` derived 64 commands (identical set to round 1); every one ran as `bash -c CMD > log 2>&1; code=$?` and was recorded as `CMD :: exit CODE`; `--ran` reconciliation on tree 51e80455 exit 0: 64 derived, 59 run (all exit 0, incl. check:skills-token-ratchet + --self-test, check:skill-docs, check:skill-refs, check:doc-authoring, check:nul-bytes, check:pm-skill-id-lint, check:skill-identifier-liveness, check:skill-frame-sync, check:skill-compatibility, check:ratchet-remedy-authority, check:pm-dispatch-gates 411s, check-empty-changeset --base origin/main, check-adr-0087-registration --base origin/main), 5 NOT-MEASURED with recorded exit 3 PREREQUISITE NOT MET (built dist/ never built for this diff): check:doc-formula-expressions, check:dts-closure, check:dual-build-cjs-loads, check:lean-entry-closure, check:sourcemap-no-sources-content. CI on head 51e80455 at report time: 41 check-runs — 26 success (incl. Lint & Repo Gates, TypeScript Type Check, Build Core, Governed Surface Queue Guard, Check Changeset, Check PR Size, PR-body guards, Lint UI, Type Check UI, Test UI, Build & E2E UI, Live E2E UI, Dogfood Regression Gate, Dogfood Verify CLI, Temporal Conformance), 14 skipped (opt-in / matrix placeholders), 1 in_progress (Test Core (1/8)). Not re-run locally; convergence is the PM's read. Round-1 review of head 2993d737 (comment 6475700322) saw 42 runs all completed, 28 success, none red.", "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm", "mcp_calls": "0 — no MCP GitHub calls this round; reads via gh api, writes via scripts/pm/ relay tools", "api_writes": "This round: 1 REST write via the fleet relay — this os-dev-report comment (POST /repos/objectstack-ai/objectstack/issues/27223/comments via post-stamped). Plus git push x1 (51e80455; not REST). No PR body edit, no labels, no ready flip. Cumulative on the card: pr_create stroke (2 requests) + 2 comments.", "deviations": [ "PR body NOT corrected via the relay: .claude/agents/os-dev.md binds the dev to write the PR body once and never PATCH it (the seat writes later changes), and the relay's only body-editing op is `issue_patch` on `/issues/{n}` (an issues op; the coordinator's own fallback applies). Corrections for the seat, verbatim: (a) 'grows by 3,370 tokens' -> 'grows by a net 3,389 tokens (SKILL.md 6466 -> 6457 = -9; integration-recipes.md +2,204; integrations-declared.json +1,194; bundle total 215,826 -> 219,215)'; (b) 'net -1 token under the ratchet' -> 'net -9 tokens'; (c) recipes '2177' -> '2204', eval '1193' -> '1194' in What changes and the Verification table (SKILL.md tokens 6466 -> 6457; lines 451 -> 450; package SKILL.md line sum 4615 -> 4614); (d) 'Head 2993d737 … no commit followed' -> 'Head 51e80455 (patch round)'; (e) add under What changes: 'In-place adjacent fix (same file, same class, mechanical): the flow-type table's `api` row said the flow needs a start-node `secret`; the start node takes `secretRef` (a name the deployment fills) or a literal `secret`, one required, both together refused — packages/spec/src/automation/api-trigger-secret-ref.zod.ts:30,:128; packages/triggers/trigger-api/src/api-trigger.ts:267-270 — so the row now names `secretRef` (or a literal `secret`).'", "Eval 1 keeps `token:` in must_not_contain (reviewer flagged only `clientSecret`): the bundle spells the refused inline shape as `authentication: { token }`, which `token:` does not match; only an authored `token: '…'` key trips it.", "The recipes file stays at 150 lines by folding two prose lines (the intro's final sentence and recipe 1's trailer), not by cutting content." ], "line_budget": { "skills/objectstack-automation/SKILL.md": "lines 451 -> 450 (base 451); tokens 6465 -> 6457 this round (base 6466; net -9; ceiling re-locked 6457, headroom 0)", "skills/objectstack-automation/references/integration-recipes.md": "150 lines (unchanged); 8705 -> 8814 bytes, 2177 -> 2204 tokens (+27, the widened `$ref` wording); row moved by the measured delta", "skills/objectstack-automation/evals/integrations-declared.json": "35 lines; 4772 -> 4773 bytes, 1193 -> 1194 tokens; row moved by the measured delta", "package": "sum of all skills/*/SKILL.md lines 4615 -> 4614; bundle total 215826 (base) -> 219215 (net +3389)", "commit": "51e80455: 4 files, +43 / -28" }, "files_changed": [ "skills/objectstack-automation/SKILL.md (+13/-14)", "skills/objectstack-automation/references/integration-recipes.md (+6/-6)", "skills/objectstack-automation/evals/integrations-declared.json (+1/-1)", "scripts/check-skills-token-ratchet.mjs (+23/-7: SKILL.md row 6465 -> 6457; eval row 1193 -> 1194; recipes row 2177 -> 2204, each with its arithmetic)" ], "open_questions": [], "out_of_scope_findings": [ "unchanged from report comment 6475198480: the class-c `connectorConfig.input` finding (FlowSchema accepts a CEL envelope, executor sends it as written) still awaits the seat's filing; the four observations stand", "observation (this round): in-document `$ref` parameters / request bodies / responses are skipped by the openapi loader (openapi-connector.ts:295, :336, :342) with no boot diagnostic — the reviewer named it, the recipe now states it; whether it merits a card under #26709's normalization item is the PM's read · carrier: #26709 (candidate)" ] }objectstack-fleet commentedon Oct 28, 2026
epic:#27293#1 · sunhaolin · session_017xRBcVBKAFk1ntXSjvPt7U
ACCEPT → PR #27322 comment 6476475773 · head
51e80455· 2026-10-28T17:52Z. Contract review PASS6475700322(2993d737) and delta PASS6476424433(51e80455). In the merge queue by the maintainer (os-zhuang, 2026-10-28T17:49Z).Acceptance wording, corrected on the record: "
pnpmskill evals green with the three new cases" cannot be met as spelled, because no script in the root repo consumesskills/*/evals/*.json(onlyui/gates its own bundle). The cases were judged by reading them against the shipped bundle and the runtime (both review records ④): the DocuSign case's required tokens are absent from the base bundle and taught by this head, and itsmust_not_containrefuses every plugin answer. Whether the root catalog should get an eval runner is not decided here.Out-of-scope dispositions:
filed #27327(connectorConfig.inputis sent as written) · in-document$refskipped by the openapi loader with no diagnostic → carrier #26709 (its normalization item) · the package-schedule deployment-policy switch is taught nowhere in the skill → noted, not filed.objectstack-fleet commentedon Oct 28, 2026
epic:#27293#1 · sunhaolin · session_017xRBcVBKAFk1ntXSjvPt7U
MERGED → PR #27322 through the merge queue (queued by the maintainer) · 2026-10-28T18:33Z. Closed
completedby itsFixes #27223;pm:dispatchedremoved in this act,pm:epickept as subtree membership. Follow-up cards: #27327 (connectorConfig.inputsent as written).