You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
skills: teach the mcp provider's providerConfig.toolsSnapshot pin in skills/objectstack-automation, the Skills-docs follow-up PR #28515 owes #28582
Filing gate: a follow-up owed by landed work. PR #28515 (merged as 76b4ae446, Fixes #27401) added the mcp provider's providerConfig.toolsSnapshot: a sha256 pin per tool, where a changed definition degrades through CONNECTOR_UPSTREAM_CHANGED. It documented the pin in content/docs/automation/connectors.mdx and deliberately left skills/** alone, because that surface is governed (Tier H). The dev's report says so: "Skills-docs: follow-up owed — skills/** not edited (Tier H)". Child of #27293 (E3, author recipes). ⛔ Not a claim.
Work
Decide whether the integration recipe in skills/objectstack-automation/references/integration-recipes.md (the mcp recipe, near the include: ['search_issues'] example at :82, read at origin/main76b4ae446) should teach the pin. If it should, add one short paragraph or bullet covering three things:
what toolsSnapshot pins, and that every pinned name must also be listed in include;
where the digests come from: computeMcpToolsSnapshot, or the digest the degraded reason prints;
what an author sees when a pin no longer matches.
Link to /docs/automation/connectors for the rest. The paragraph is paid for under the skills token ratchet. If the skills seat judges the pin too niche for a recipe, record that judgement on this card and close it as not planned.
Business reason
An app-authoring agent reads the skills first. Without the pin in the recipe, the GitHub connector app (and every MCP app after it) is authored with no protection against a server silently changing what a tool means. That is the exposure #27401 was opened to close.
Reader
The skills seat (domain:skills). Triage grades and routes it.
Dedupe
The 500 most recent issues and PRs (read 2026-11-01T06:21Z), titles grepped for toolsSnapshot|tool snapshot|tool-snapshot: 1 hit, PR #28515 itself. Control skills on the same set: 35 hits.
Claim: PM loop round 4
Session: session_017xRBcVBKAFk1ntXSjvPt7U
Account: sunhaolin (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/issue-28582-skills-tools-snapshot
Worktree: objectstack-issue-28582
Domain: domain:skills
Seat: epic:#27293#1
File surface: skills/objectstack-automation/references/integration-recipes.md (the mcp recipe; one short paragraph or bullet on providerConfig.toolsSnapshot, linking /docs/automation/connectors), and only what the skills token ratchet and skills gates require beside it (stop on breach; explain in the report). Or no edit at all: if the seat judges the pin too niche for a recipe, the report records that judgement and the card closes not planned
Container & model: S, mode:subagent, model: fable (MANDATORY — dispatch-gates --tier --repo objectstack-ai/objectstack this fire: skills/** clause ①, no one-line exit), effort: high
Clause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card
Thread-read: 6554667567
Premise: holds (read at origin/maincd065d36 2026-11-01T07:11Z: the recipe's mcp example is at integration-recipes.md:82 (include: ['search_issues']); toolsSnapshot 0 hits under skills/; PR #28515 merged as 76b4ae446)
Serial constraints cleared: none — none of the 60 most recent open PRs touches skills/objectstack-automation/** (files read 2026-11-01T07:11Z). Landing: skills/** is governed (Tier H) — the PR waits on the maintainer.
{
"issue": 28582,
"status": "done",
"branch": "claude/issue-28582-skills-tools-snapshot",
"pr": "https://github.com/objectstack-ai/objectstack/pull/28597",
"session": "session_017xRBcVBKAFk1ntXSjvPt7U",
"premise_still_valid": true,
"summary": "Judgement: the pin is not too niche for the recipe — it is one key beside the `include` the recipe already shows, and an app author has a no-code route to the digests (a 64-hex placeholder pin, then the served digest the degraded reason prints on `GET /api/v1/automation/connectors`). Added one paragraph under recipe 2 (remote MCP) of `skills/objectstack-automation/references/integration-recipes.md`: what `toolsSnapshot` pins and that a pinned name `include` leaves out is refused at boot; digests via `computeMcpToolsSnapshot(tools)` or the degraded reason; a pinned tool served differently degrades the instance with no actions (`CONNECTOR_UPSTREAM_CHANGED`), one no longer listed too, the reason naming each tool and the served digest; link to the connectors page pin section. Every clause read off `mcp-provider.ts` / `tool-snapshot.ts` at base `cd065d36`. Paid under the skills token ratchet (file was 2488/2488) by deleting same-file restatements with a surviving home (SKILL.md `connector_action` row and Signature bullet, objectstack-platform `requires` rule, connectors page, recipe 1's own comment); lands 2487/2488, no ceiling moved. Changeset `@objectstack/skills` patch. Draft PR #28597 on head 64882e22; `skills/**` is Tier H so it waits for the maintainer.",
"skills_readings": "integration-recipes.md lines 176 -> 178, bytes 9949 -> 9946, ratchet tokens 2488 -> 2487 (ceiling 2488, headroom 0 -> 1); whole skills/** tracked lines 19546 -> 19548; all 11 SKILL.md lines 4587 -> 4587 (untouched); bundle total tokens 221928 -> 221927",
"tests": "No package touched: closure ① empty, no package test/typecheck owed, no tested behaviour changed, no ablation. Ratchet read in both directions on this tree: intermediate red `integration-recipes.md is 2496 tokens; the ratchet ceiling is 2488 (over by 8)` exit 1, final green `integration-recipes.md is 2487 tokens (ceiling 2488; headroom 1)` + `57 authored bundle file(s) within their ceilings` exit 0. Control-char scan `grep -naP '[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]'` on the two edited files: no match (exit 1). Build under lock for gate 19's prerequisite: `turbo run build --filter=@objectstack/formula --filter=@objectstack/lint` → `os-verify-lock: VERDICT command-exit 0 · held the lock 2s · waited 0s`.",
"gates": "Derived with `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` on head 64882e22 (2 paths vs merge base cd065d36): 44 commands, each run with exit captured before any pipe into ran.list; `--ran` verdict: `✓ dispatch-gates --ran: 44 derived famil(ies) accounted for — 40 run, 4 NOT-MEASURED (4 DERIVED from a recorded exit 3).` 0 UNRUN. All 40 run exit 0, among them check-skills-token-ratchet, check:skill-identifier-liveness, check:skill-frame-sync, check:skill-compatibility, spec check:skill-refs, check:nul-bytes, check:doc-authoring, check:pm-skill-id-lint, check:empty-changeset, check:changeset-no-major, check:adr-0087-registration, check:closing-keyword-parity, check:published-files, check:pm-governed-merges; lint check:doc-formula-expressions exit 3 first (dist absent), exit 0 after the formula+lint build. NOT MEASURED (exit 3 PREREQUISITE NOT MET, each needs the whole 129-package closure built, which this diff does not touch): check:dts-closure, check:dual-build-cjs-loads, check:lean-entry-closure, check:sourcemap-no-sources-content — CI runs them. Not run locally by rule: pnpm lint, test:repo, the repo-wide farm. PR check-runs: in_progress at report time (PR opened moments before this report; read them off #28597).",
"dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
"mcp_calls": "0 — no MCP GitHub calls (reads via `gh api` GET: issue 28582 + comments once, pull 28597 once)",
"api_writes": "2 — relay strokes as objectstack-fleet[bot]: POST /repos/objectstack-ai/objectstack/pulls (pr_create, request fw-20261101T073228Z-f1c956, run 41285191571, PR #28597, draft, no labels, no assignees); POST /repos/objectstack-ai/objectstack/issues/28582/comments (this os-dev-report via post-stamped.mjs). Plus 2 `git push` to origin/claude/issue-28582-skills-tools-snapshot (empty probe branch, then 64882e22) — git, not REST.",
"deviations": [
"Commit trailer: the harness attribution reminder's `Co-Authored-By: Claude Fable 5.1` was refused by the pre-push hook (check:commit-card-trailers, model identifier); the unpublished tip was amended to the AGENTS.md model-free pair (`Claude-Session:` + `Co-authored-by: Claude`) before any push — no published history rewritten.",
"4 derived families NOT MEASURED locally (whole-closure dist prerequisite; listed in gates); declared to CI.",
"No labels sent on pr_create: the dispatch named none and `skip-changeset` does not apply (the skills/** tree publishes as @objectstack/skills, so a patch changeset is included)."
],
"open_questions": [],
"out_of_scope_findings": [
"carrier: none · noted, not filed (observation, not a contract violation): `content/docs/automation/connectors.mdx` failure-mode table row for the pin folds the 'pinned tool no longer listed' case under CONNECTOR_UPSTREAM_CHANGED, while its own prose and `mcp-provider.ts` route that case to the credential-rejected path (403, `pinnedToolsHiddenError`) when the instance's credential reached the server; the prose is right, the row is a summary. Dedupe words: toolsSnapshot table row, pinnedToolsHiddenError, credential path, connectors.mdx failure modes.",
"carrier: none · noted, not filed (no CLI prints an MCP server's tool digests; the docs page states the code route and the placeholder-pin route is what the runtime delivers, so this is a convenience gap, not a defect): an `os` subcommand that lists a server's tools with their `mcpToolDigest` would remove the need to boot once. Dedupe words: mcpToolDigest CLI, tools/list digest, computeMcpToolsSnapshot command."
]
}
{
"issue": 28582,
"status": "done",
"delta_of": "os-dev-report comment 6555022020 (head 64882e22) — review round: two must-fixes in the skill text plus the connectors.mdx table-row addendum",
"branch": "claude/issue-28582-skills-tools-snapshot",
"pr": "https://github.com/objectstack-ai/objectstack/pull/28597",
"head": "7a8da47c (pushed to the same branch; PR body not edited)",
"session": "session_017xRBcVBKAFk1ntXSjvPt7U",
"premise_still_valid": true,
"summary": "Must-fix 1: the recipe-2 paragraph now states both missing-pin outcomes off `credentialSent` in `mcp-provider.ts`: a pinned tool served differently is `CONNECTOR_UPSTREAM_CHANGED` with the digest it now serves (review, re-pin); one no longer listed is the credential path when the instance's credential reached the server, as recipe 2's `bearer` does — the stored credential marked `rejected`: fix the credential and set it again, or update the pin — and `CONNECTOR_UPSTREAM_CHANGED` otherwise. Must-fix 2: restored `Keep automation in requires whenever a connector is declared.` in the recipe file's intro (reading for the record: objectstack-platform SKILL.md:381 also carries `Keep automation whenever plugins: lists a connector`, framed on plugins:, not on a connectors: declaration; the sentence is restored here as ruled). Addendum: `content/docs/automation/connectors.mdx` failure-mode table row for the pin now names the same two cases (its left cell scopes the UPSTREAM_CHANGED outcome for a missing tool to an instance whose credential did not reach the server; the right cell adds the credential-row outcome for one whose credential did), one row, nothing else on the page. Paid under the ratchet by same-file cuts with a surviving home: recipe 6's vendor-redirect clause and the agent/API-key aside (connectors page), recipe 3's `defaultHeaders` and the auth bullet's `X-API-Key` default (connectors page), recipe 2's stdio comment shortened and recipe 4's door sentence tightened (SKILL.md:414 and the connectors table), recipe 1's `$ref` sentence tightened, and the `Not yet` section folded into the Holds `auth` bullet (WeChat Pay: mark blocked, write no plugin — SKILL.md § Integrations says the same). Every other deletion from round 1 kept.",
"skills_readings": "integration-recipes.md lines 176 (base) -> 177, bytes 9949 -> 9951, ratchet tokens 2488 -> 2488 (ceiling 2488, headroom now 0); whole skills/** tracked lines 19546 -> 19547; all 11 SKILL.md lines 4587 (untouched); bundle total tokens 221928 -> 221928. Diff vs base cd065d36: 3 files, +50/-37.",
"tests": "Ratchet on head 7a8da47c: `✓ check-skills-token-ratchet: skills/objectstack-automation/references/integration-recipes.md is 2488 tokens (ceiling 2488; headroom 0).` exit 0 (an intermediate state read `2527 tokens; ceiling 2488 (over by 39)` exit 1 before the cuts). Control-char scan on the two edited files: no match (exit 1). No package code touched; no ablation. Builds under os-verify-lock for gate prerequisites only, all `VERDICT command-exit 0`: spec+formula+lint via turbo (FULL TURBO cache), `pnpm --filter @objectstack/spec build` direct (61s; `git status` clean after — no generated artifact moved), client+client-react closure (38 tasks, 126s).",
"gates": "`node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` on head 7a8da47c (3 paths vs merge base cd065d36): 68 commands (the docs page adds 24 docs families), each run with the exit captured before any pipe; `--ran` verdict: `✓ dispatch-gates --ran: 68 derived famil(ies) accounted for — 64 run, 4 NOT-MEASURED (4 DERIVED from a recorded exit 3).` 0 UNRUN. 64 run exit 0, including check-skills-token-ratchet, check:skill-identifier-liveness, check:skill-frame-sync, check:skill-compatibility, spec check:skill-refs / check:docs / check:skill-examples / check:liveness / check:empty-state / check:variant-docs / check:yaml-examples / check:strictness-ledger, lint check:doc-formula-expressions / check:doc-security-posture, check:doc-anchors, check:doc-frontmatter, check:docs-single-h1, check:docs-redirects, check:docs-spec-enumerations, check:docs-transcript-drift, check:docs-audit-scope, check:adr-links, check:docs-section-name, check:section-landing-index, check:published-readme-links, check:nul-bytes, check:doc-authoring, check:pm-skill-id-lint, check:empty-changeset, check:changeset-no-major, check:adr-0087-registration, check:closing-keyword-parity, check:published-files, check:pm-governed-merges. Five first answered exit 3 on the fresh worktree's missing dist (doc-formula-expressions, doc-security-posture, spec check:docs [exit 1, 'generate the tree first'], skill-examples, docs-transcript-drift) and re-ran exit 0 after the builds above. NOT MEASURED, 4 (exit 3 PREREQUISITE NOT MET; each reads the whole 129-package closure's dist/, untouched by this diff): check:dts-closure, check:dual-build-cjs-loads, check:lean-entry-closure, check:sourcemap-no-sources-content — CI's. PR check-runs on 7a8da47c: in_progress at report time.",
"dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
"mcp_calls": "0 — no MCP GitHub calls",
"api_writes": "1 this round — relay stroke as objectstack-fleet[bot]: POST /repos/objectstack-ai/objectstack/issues/28582/comments (this delta via post-stamped.mjs). Plus 1 `git push` (7a8da47c) — git, not REST. Cumulative: 3 relay writes (pr_create, report, delta), 3 pushes. PR body untouched (no PATCH).",
"deviations": [
"The worktree had been removed at round-1 cleanup; it was re-created from origin/claude/issue-28582-skills-tools-snapshot@64882e22 (Resume-from shape), `pnpm install`, and the gate prerequisites rebuilt under the lock.",
"integration-recipes.md now sits at headroom 0 (2488/2488): any further sentence in that file must be paid for again.",
"The changeset text was not reworded for the docs-row fix (content/docs is not a published package surface); the changeset still describes the skills change accurately."
],
"open_questions": [],
"out_of_scope_findings": [
"carrier: none · noted, not filed (convenience gap): no `os` subcommand prints an MCP server's tools with their `mcpToolDigest`; an author without code boots once with a placeholder pin to read the served digests. Dedupe words: mcpToolDigest CLI, tools/list digest, computeMcpToolsSnapshot command."
]
}
{
"issue": 28582,
"status": "done",
"delta_of": "os-dev-report comments 6555022020 (head 64882e22) and 6555246752 (head 7a8da47c) — review round 2: restore the two recipe-6 guardrails and pay only with skills/-homed text",
"branch": "claude/issue-28582-skills-tools-snapshot",
"pr": "https://github.com/objectstack-ai/objectstack/pull/28597",
"head": "71213196 (pushed to the same branch; PR body not edited)",
"session": "session_017xRBcVBKAFk1ntXSjvPt7U",
"premise_still_valid": true,
"summary": "Restored in recipe 6, verbatim as at base: `(an agent or API key is refused)` and `the vendor redirects to GET …/connectors/oauth/callback` (the eval integrations-declared.json:7 expectation). Paid under the ratchet only with text restated elsewhere in skills/ (git grep on this branch): recipe 1's `// a scheduled run has no trigger user` (examples-flows.md:23 and :88 carry it verbatim); recipe 1's `// multi-tenant: pin the organization too` (SKILL.md:167, `A runAs: 'system' sweep must pin its organization`); the WeChat aside's `mark it blocked, write no plugin` half (SKILL.md § Integrations are declared, not coded — the clause now reads `WeChat Pay has no scheme yet: blocked`); and one wording tightening in the toolsSnapshot paragraph that drops no fact (`the reason on GET … naming each tool` → `the GET … reason names each tool`). No other text cut; the file is UNDER the ceiling, so no ceiling question for the maintainer. Of the smaller round-1 losses the PM listed, `(organization admins by default)`, the `X-API-Key` default, `GET reads the status; DELETE revokes` and recipe 3's `defaultHeaders` stay cut: each has a home only on the connectors page, and restoring all four (≈150 bytes) would put the file over the ceiling again — flagged here as the trade, not decided.",
"skills_readings": "integration-recipes.md lines 176 (base) -> 178, bytes 9949 -> 9926, ratchet tokens 2488 -> 2482 (ceiling 2488, headroom 6); whole skills/** tracked lines 19546 -> 19548; all 11 SKILL.md lines 4587 (untouched); bundle total tokens 221928 -> 221922. Diff vs base cd065d36: 3 files (+53/-39): the recipe file, the connectors.mdx table row, the changeset.",
"tests": "Ratchet on head 71213196: `✓ check-skills-token-ratchet: skills/objectstack-automation/references/integration-recipes.md is 2482 tokens (ceiling 2488; headroom 6).` exit 0 (intermediate, before the organization-comment cut: `2492 tokens; … over by 4` exit 1). Control-char scan: no match (exit 1). `git grep -c` on the branch: `oauth/callback` and `an agent or API key is refused` both present in the recipe file (2 hits). No package code touched; no ablation. No eval fixture edited; no `check:*eval*` script exists in root or packages/spec package.json (the eval-adjacent gates are in the derived list below and ran green).",
"gates": "`node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` on head 71213196 (3 paths vs merge base cd065d36): 68 commands, each run with the exit captured before any pipe; `--ran` verdict: `✓ dispatch-gates --ran: 68 derived famil(ies) accounted for — 67 run, 1 NOT-MEASURED (1 DERIVED from a recorded exit 3).` 0 UNRUN. 67 exit 0 on this head — the dist/ built last round under os-verify-lock (spec direct, formula, lint, client, client-react) stayed in place, so check:dts-closure, check:lean-entry-closure, check:sourcemap-no-sources-content, spec check:docs / check:skill-examples / check:skill-refs / check:liveness / check:empty-state / check:variant-docs / check:yaml-examples, lint check:doc-formula-expressions / check:doc-security-posture, check:docs-transcript-drift, check-skills-token-ratchet (+ --self-test), check:skill-identifier-liveness, check:skill-frame-sync, check:skill-compatibility, the docs gates (doc-anchors, doc-frontmatter, docs-single-h1, docs-redirects, docs-spec-enumerations, docs-audit-scope, adr-links, docs-section-name, section-landing-index, published-readme-links), check:nul-bytes, check:doc-authoring, check:pm-skill-id-lint, check:empty-changeset, check:changeset-no-major, check:adr-0087-registration, check:closing-keyword-parity, check:published-files, check:pm-governed-merges all measured green. NOT MEASURED, 1: check:dual-build-cjs-loads (exit 3 PREREQUISITE NOT MET — it needs every one of the 129 packages built; CI's). PR check-runs on 71213196: in_progress at report time.",
"dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
"mcp_calls": "0 — no MCP GitHub calls",
"api_writes": "1 this round — relay stroke as objectstack-fleet[bot]: POST /repos/objectstack-ai/objectstack/issues/28582/comments (this delta via post-stamped.mjs). Plus 1 `git push` (71213196) — git, not REST. Cumulative: 4 relay writes (pr_create, report, delta, delta 2), 4 pushes. PR body untouched (no PATCH).",
"deviations": [
"Round-1 cuts with a docs-page-only home that remain cut (listed in summary) — restoring them is a ceiling question for the maintainer on this Tier H PR; headroom today is 6 tokens (≈24 bytes)."
],
"open_questions": [],
"out_of_scope_findings": [
"carrier: none · noted, not filed (convenience gap): no `os` subcommand prints an MCP server's tools with their `mcpToolDigest`; an author without code boots once with a placeholder pin to read the served digests. Dedupe words: mcpToolDigest CLI, tools/list digest, computeMcpToolsSnapshot command."
]
}
MERGED → PR #28597 through the merge queue (merge commit 28f2e99b8, queued by os-zhuang) · 2026-11-01T10:23Z. Closed completed by its Fixes #28582. pm:dispatched is removed in this act; pm:epic is kept. skills/objectstack-automation/references/integration-recipes.md now teaches providerConfig.toolsSnapshot on the MCP recipe: the pin, its digests, and the two mismatch outcomes split on whether the instance's credential reached the server. The connectors page's failure-mode row agrees with it. This closes the Skills-docs follow-up PR #28515 owed. The two optional nits in the seat record 6555464359 (64 lowercase hex; the DELETE revokes clause that eval 1 names) were not taken.
Activity
objectstack-fleet commentedon Nov 1, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: 写给 AI 的文档与 skills 说错一句,等于产品缺陷 | none | P①
Triage: p2 ·
domain:skills·area:automation·pm:epickept · 2026-11-01T06:55Z⛔ Not a claim.
76b4ae446) owes this skills follow-up for thetoolsSnapshotpin.skills/**is Tier H, so its PR is reviewed at that tier.not plannedneeds that judgement recorded on the card.pm:epicstays. The epic PM of [Epic] Marketplace and connector auto-shelf — E1 platform prerequisites (openapi/mcp hardening, outbound OAuth, request signing), E2 administrator credential hand-off, E3 author recipes and handbook, E4 the first shelf of official connector apps #27293 dispatches it.Generated by Claude Code
objectstack-fleet commentedon Nov 1, 2026
epic:#27293#1 · sunhaolin · session_017xRBcVBKAFk1ntXSjvPt7U
Claim: PM loop round 4
Session:
session_017xRBcVBKAFk1ntXSjvPt7UAccount:
sunhaolin(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-28582-skills-tools-snapshotWorktree:
objectstack-issue-28582Domain:
domain:skillsSeat:
epic:#27293#1File surface:
skills/objectstack-automation/references/integration-recipes.md(themcprecipe; one short paragraph or bullet onproviderConfig.toolsSnapshot, linking/docs/automation/connectors), and only what the skills token ratchet and skills gates require beside it (stop on breach; explain in the report). Or no edit at all: if the seat judges the pin too niche for a recipe, the report records that judgement and the card closesnot plannedContainer & model:
S,mode:subagent,model: fable(MANDATORY —dispatch-gates --tier --repo objectstack-ai/objectstackthis fire:skills/**clause ①, no one-line exit),effort: highClause-②: no
Metadata-protocol: none
Responsibility:
n/a — not a defect cardThread-read: 6554667567
Premise: holds (read at
origin/maincd065d362026-11-01T07:11Z: the recipe'smcpexample is atintegration-recipes.md:82(include: ['search_issues']);toolsSnapshot0 hits underskills/; PR #28515 merged as76b4ae446)Serial constraints cleared:
none— none of the 60 most recent open PRs touchesskills/objectstack-automation/**(files read 2026-11-01T07:11Z). Landing:skills/**is governed (Tier H) — the PR waits on the maintainer.objectstack-fleet commentedon Nov 1, 2026
epic:#27293#1 · sunhaolin · session_017xRBcVBKAFk1ntXSjvPt7U
os-dev-report
{ "issue": 28582, "status": "done", "branch": "claude/issue-28582-skills-tools-snapshot", "pr": "https://github.com/objectstack-ai/objectstack/pull/28597", "session": "session_017xRBcVBKAFk1ntXSjvPt7U", "premise_still_valid": true, "summary": "Judgement: the pin is not too niche for the recipe — it is one key beside the `include` the recipe already shows, and an app author has a no-code route to the digests (a 64-hex placeholder pin, then the served digest the degraded reason prints on `GET /api/v1/automation/connectors`). Added one paragraph under recipe 2 (remote MCP) of `skills/objectstack-automation/references/integration-recipes.md`: what `toolsSnapshot` pins and that a pinned name `include` leaves out is refused at boot; digests via `computeMcpToolsSnapshot(tools)` or the degraded reason; a pinned tool served differently degrades the instance with no actions (`CONNECTOR_UPSTREAM_CHANGED`), one no longer listed too, the reason naming each tool and the served digest; link to the connectors page pin section. Every clause read off `mcp-provider.ts` / `tool-snapshot.ts` at base `cd065d36`. Paid under the skills token ratchet (file was 2488/2488) by deleting same-file restatements with a surviving home (SKILL.md `connector_action` row and Signature bullet, objectstack-platform `requires` rule, connectors page, recipe 1's own comment); lands 2487/2488, no ceiling moved. Changeset `@objectstack/skills` patch. Draft PR #28597 on head 64882e22; `skills/**` is Tier H so it waits for the maintainer.", "skills_readings": "integration-recipes.md lines 176 -> 178, bytes 9949 -> 9946, ratchet tokens 2488 -> 2487 (ceiling 2488, headroom 0 -> 1); whole skills/** tracked lines 19546 -> 19548; all 11 SKILL.md lines 4587 -> 4587 (untouched); bundle total tokens 221928 -> 221927", "tests": "No package touched: closure ① empty, no package test/typecheck owed, no tested behaviour changed, no ablation. Ratchet read in both directions on this tree: intermediate red `integration-recipes.md is 2496 tokens; the ratchet ceiling is 2488 (over by 8)` exit 1, final green `integration-recipes.md is 2487 tokens (ceiling 2488; headroom 1)` + `57 authored bundle file(s) within their ceilings` exit 0. Control-char scan `grep -naP '[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]'` on the two edited files: no match (exit 1). Build under lock for gate 19's prerequisite: `turbo run build --filter=@objectstack/formula --filter=@objectstack/lint` → `os-verify-lock: VERDICT command-exit 0 · held the lock 2s · waited 0s`.", "gates": "Derived with `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` on head 64882e22 (2 paths vs merge base cd065d36): 44 commands, each run with exit captured before any pipe into ran.list; `--ran` verdict: `✓ dispatch-gates --ran: 44 derived famil(ies) accounted for — 40 run, 4 NOT-MEASURED (4 DERIVED from a recorded exit 3).` 0 UNRUN. All 40 run exit 0, among them check-skills-token-ratchet, check:skill-identifier-liveness, check:skill-frame-sync, check:skill-compatibility, spec check:skill-refs, check:nul-bytes, check:doc-authoring, check:pm-skill-id-lint, check:empty-changeset, check:changeset-no-major, check:adr-0087-registration, check:closing-keyword-parity, check:published-files, check:pm-governed-merges; lint check:doc-formula-expressions exit 3 first (dist absent), exit 0 after the formula+lint build. NOT MEASURED (exit 3 PREREQUISITE NOT MET, each needs the whole 129-package closure built, which this diff does not touch): check:dts-closure, check:dual-build-cjs-loads, check:lean-entry-closure, check:sourcemap-no-sources-content — CI runs them. Not run locally by rule: pnpm lint, test:repo, the repo-wide farm. PR check-runs: in_progress at report time (PR opened moments before this report; read them off #28597).", "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm", "mcp_calls": "0 — no MCP GitHub calls (reads via `gh api` GET: issue 28582 + comments once, pull 28597 once)", "api_writes": "2 — relay strokes as objectstack-fleet[bot]: POST /repos/objectstack-ai/objectstack/pulls (pr_create, request fw-20261101T073228Z-f1c956, run 41285191571, PR #28597, draft, no labels, no assignees); POST /repos/objectstack-ai/objectstack/issues/28582/comments (this os-dev-report via post-stamped.mjs). Plus 2 `git push` to origin/claude/issue-28582-skills-tools-snapshot (empty probe branch, then 64882e22) — git, not REST.", "deviations": [ "Commit trailer: the harness attribution reminder's `Co-Authored-By: Claude Fable 5.1` was refused by the pre-push hook (check:commit-card-trailers, model identifier); the unpublished tip was amended to the AGENTS.md model-free pair (`Claude-Session:` + `Co-authored-by: Claude`) before any push — no published history rewritten.", "4 derived families NOT MEASURED locally (whole-closure dist prerequisite; listed in gates); declared to CI.", "No labels sent on pr_create: the dispatch named none and `skip-changeset` does not apply (the skills/** tree publishes as @objectstack/skills, so a patch changeset is included)." ], "open_questions": [], "out_of_scope_findings": [ "carrier: none · noted, not filed (observation, not a contract violation): `content/docs/automation/connectors.mdx` failure-mode table row for the pin folds the 'pinned tool no longer listed' case under CONNECTOR_UPSTREAM_CHANGED, while its own prose and `mcp-provider.ts` route that case to the credential-rejected path (403, `pinnedToolsHiddenError`) when the instance's credential reached the server; the prose is right, the row is a summary. Dedupe words: toolsSnapshot table row, pinnedToolsHiddenError, credential path, connectors.mdx failure modes.", "carrier: none · noted, not filed (no CLI prints an MCP server's tool digests; the docs page states the code route and the placeholder-pin route is what the runtime delivers, so this is a convenience gap, not a defect): an `os` subcommand that lists a server's tools with their `mcpToolDigest` would remove the need to boot once. Dedupe words: mcpToolDigest CLI, tools/list digest, computeMcpToolsSnapshot command." ] }objectstack-fleet commentedon Nov 1, 2026
epic:#27293#1 · sunhaolin · session_017xRBcVBKAFk1ntXSjvPt7U
os-dev-report
{ "issue": 28582, "status": "done", "delta_of": "os-dev-report comment 6555022020 (head 64882e22) — review round: two must-fixes in the skill text plus the connectors.mdx table-row addendum", "branch": "claude/issue-28582-skills-tools-snapshot", "pr": "https://github.com/objectstack-ai/objectstack/pull/28597", "head": "7a8da47c (pushed to the same branch; PR body not edited)", "session": "session_017xRBcVBKAFk1ntXSjvPt7U", "premise_still_valid": true, "summary": "Must-fix 1: the recipe-2 paragraph now states both missing-pin outcomes off `credentialSent` in `mcp-provider.ts`: a pinned tool served differently is `CONNECTOR_UPSTREAM_CHANGED` with the digest it now serves (review, re-pin); one no longer listed is the credential path when the instance's credential reached the server, as recipe 2's `bearer` does — the stored credential marked `rejected`: fix the credential and set it again, or update the pin — and `CONNECTOR_UPSTREAM_CHANGED` otherwise. Must-fix 2: restored `Keep automation in requires whenever a connector is declared.` in the recipe file's intro (reading for the record: objectstack-platform SKILL.md:381 also carries `Keep automation whenever plugins: lists a connector`, framed on plugins:, not on a connectors: declaration; the sentence is restored here as ruled). Addendum: `content/docs/automation/connectors.mdx` failure-mode table row for the pin now names the same two cases (its left cell scopes the UPSTREAM_CHANGED outcome for a missing tool to an instance whose credential did not reach the server; the right cell adds the credential-row outcome for one whose credential did), one row, nothing else on the page. Paid under the ratchet by same-file cuts with a surviving home: recipe 6's vendor-redirect clause and the agent/API-key aside (connectors page), recipe 3's `defaultHeaders` and the auth bullet's `X-API-Key` default (connectors page), recipe 2's stdio comment shortened and recipe 4's door sentence tightened (SKILL.md:414 and the connectors table), recipe 1's `$ref` sentence tightened, and the `Not yet` section folded into the Holds `auth` bullet (WeChat Pay: mark blocked, write no plugin — SKILL.md § Integrations says the same). Every other deletion from round 1 kept.", "skills_readings": "integration-recipes.md lines 176 (base) -> 177, bytes 9949 -> 9951, ratchet tokens 2488 -> 2488 (ceiling 2488, headroom now 0); whole skills/** tracked lines 19546 -> 19547; all 11 SKILL.md lines 4587 (untouched); bundle total tokens 221928 -> 221928. Diff vs base cd065d36: 3 files, +50/-37.", "tests": "Ratchet on head 7a8da47c: `✓ check-skills-token-ratchet: skills/objectstack-automation/references/integration-recipes.md is 2488 tokens (ceiling 2488; headroom 0).` exit 0 (an intermediate state read `2527 tokens; ceiling 2488 (over by 39)` exit 1 before the cuts). Control-char scan on the two edited files: no match (exit 1). No package code touched; no ablation. Builds under os-verify-lock for gate prerequisites only, all `VERDICT command-exit 0`: spec+formula+lint via turbo (FULL TURBO cache), `pnpm --filter @objectstack/spec build` direct (61s; `git status` clean after — no generated artifact moved), client+client-react closure (38 tasks, 126s).", "gates": "`node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` on head 7a8da47c (3 paths vs merge base cd065d36): 68 commands (the docs page adds 24 docs families), each run with the exit captured before any pipe; `--ran` verdict: `✓ dispatch-gates --ran: 68 derived famil(ies) accounted for — 64 run, 4 NOT-MEASURED (4 DERIVED from a recorded exit 3).` 0 UNRUN. 64 run exit 0, including check-skills-token-ratchet, check:skill-identifier-liveness, check:skill-frame-sync, check:skill-compatibility, spec check:skill-refs / check:docs / check:skill-examples / check:liveness / check:empty-state / check:variant-docs / check:yaml-examples / check:strictness-ledger, lint check:doc-formula-expressions / check:doc-security-posture, check:doc-anchors, check:doc-frontmatter, check:docs-single-h1, check:docs-redirects, check:docs-spec-enumerations, check:docs-transcript-drift, check:docs-audit-scope, check:adr-links, check:docs-section-name, check:section-landing-index, check:published-readme-links, check:nul-bytes, check:doc-authoring, check:pm-skill-id-lint, check:empty-changeset, check:changeset-no-major, check:adr-0087-registration, check:closing-keyword-parity, check:published-files, check:pm-governed-merges. Five first answered exit 3 on the fresh worktree's missing dist (doc-formula-expressions, doc-security-posture, spec check:docs [exit 1, 'generate the tree first'], skill-examples, docs-transcript-drift) and re-ran exit 0 after the builds above. NOT MEASURED, 4 (exit 3 PREREQUISITE NOT MET; each reads the whole 129-package closure's dist/, untouched by this diff): check:dts-closure, check:dual-build-cjs-loads, check:lean-entry-closure, check:sourcemap-no-sources-content — CI's. PR check-runs on 7a8da47c: in_progress at report time.", "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm", "mcp_calls": "0 — no MCP GitHub calls", "api_writes": "1 this round — relay stroke as objectstack-fleet[bot]: POST /repos/objectstack-ai/objectstack/issues/28582/comments (this delta via post-stamped.mjs). Plus 1 `git push` (7a8da47c) — git, not REST. Cumulative: 3 relay writes (pr_create, report, delta), 3 pushes. PR body untouched (no PATCH).", "deviations": [ "The worktree had been removed at round-1 cleanup; it was re-created from origin/claude/issue-28582-skills-tools-snapshot@64882e22 (Resume-from shape), `pnpm install`, and the gate prerequisites rebuilt under the lock.", "integration-recipes.md now sits at headroom 0 (2488/2488): any further sentence in that file must be paid for again.", "The changeset text was not reworded for the docs-row fix (content/docs is not a published package surface); the changeset still describes the skills change accurately." ], "open_questions": [], "out_of_scope_findings": [ "carrier: none · noted, not filed (convenience gap): no `os` subcommand prints an MCP server's tools with their `mcpToolDigest`; an author without code boots once with a placeholder pin to read the served digests. Dedupe words: mcpToolDigest CLI, tools/list digest, computeMcpToolsSnapshot command." ] }objectstack-fleet commentedon Nov 1, 2026
epic:#27293#1 · sunhaolin · session_017xRBcVBKAFk1ntXSjvPt7U
os-dev-report
{ "issue": 28582, "status": "done", "delta_of": "os-dev-report comments 6555022020 (head 64882e22) and 6555246752 (head 7a8da47c) — review round 2: restore the two recipe-6 guardrails and pay only with skills/-homed text", "branch": "claude/issue-28582-skills-tools-snapshot", "pr": "https://github.com/objectstack-ai/objectstack/pull/28597", "head": "71213196 (pushed to the same branch; PR body not edited)", "session": "session_017xRBcVBKAFk1ntXSjvPt7U", "premise_still_valid": true, "summary": "Restored in recipe 6, verbatim as at base: `(an agent or API key is refused)` and `the vendor redirects to GET …/connectors/oauth/callback` (the eval integrations-declared.json:7 expectation). Paid under the ratchet only with text restated elsewhere in skills/ (git grep on this branch): recipe 1's `// a scheduled run has no trigger user` (examples-flows.md:23 and :88 carry it verbatim); recipe 1's `// multi-tenant: pin the organization too` (SKILL.md:167, `A runAs: 'system' sweep must pin its organization`); the WeChat aside's `mark it blocked, write no plugin` half (SKILL.md § Integrations are declared, not coded — the clause now reads `WeChat Pay has no scheme yet: blocked`); and one wording tightening in the toolsSnapshot paragraph that drops no fact (`the reason on GET … naming each tool` → `the GET … reason names each tool`). No other text cut; the file is UNDER the ceiling, so no ceiling question for the maintainer. Of the smaller round-1 losses the PM listed, `(organization admins by default)`, the `X-API-Key` default, `GET reads the status; DELETE revokes` and recipe 3's `defaultHeaders` stay cut: each has a home only on the connectors page, and restoring all four (≈150 bytes) would put the file over the ceiling again — flagged here as the trade, not decided.", "skills_readings": "integration-recipes.md lines 176 (base) -> 178, bytes 9949 -> 9926, ratchet tokens 2488 -> 2482 (ceiling 2488, headroom 6); whole skills/** tracked lines 19546 -> 19548; all 11 SKILL.md lines 4587 (untouched); bundle total tokens 221928 -> 221922. Diff vs base cd065d36: 3 files (+53/-39): the recipe file, the connectors.mdx table row, the changeset.", "tests": "Ratchet on head 71213196: `✓ check-skills-token-ratchet: skills/objectstack-automation/references/integration-recipes.md is 2482 tokens (ceiling 2488; headroom 6).` exit 0 (intermediate, before the organization-comment cut: `2492 tokens; … over by 4` exit 1). Control-char scan: no match (exit 1). `git grep -c` on the branch: `oauth/callback` and `an agent or API key is refused` both present in the recipe file (2 hits). No package code touched; no ablation. No eval fixture edited; no `check:*eval*` script exists in root or packages/spec package.json (the eval-adjacent gates are in the derived list below and ran green).", "gates": "`node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` on head 71213196 (3 paths vs merge base cd065d36): 68 commands, each run with the exit captured before any pipe; `--ran` verdict: `✓ dispatch-gates --ran: 68 derived famil(ies) accounted for — 67 run, 1 NOT-MEASURED (1 DERIVED from a recorded exit 3).` 0 UNRUN. 67 exit 0 on this head — the dist/ built last round under os-verify-lock (spec direct, formula, lint, client, client-react) stayed in place, so check:dts-closure, check:lean-entry-closure, check:sourcemap-no-sources-content, spec check:docs / check:skill-examples / check:skill-refs / check:liveness / check:empty-state / check:variant-docs / check:yaml-examples, lint check:doc-formula-expressions / check:doc-security-posture, check:docs-transcript-drift, check-skills-token-ratchet (+ --self-test), check:skill-identifier-liveness, check:skill-frame-sync, check:skill-compatibility, the docs gates (doc-anchors, doc-frontmatter, docs-single-h1, docs-redirects, docs-spec-enumerations, docs-audit-scope, adr-links, docs-section-name, section-landing-index, published-readme-links), check:nul-bytes, check:doc-authoring, check:pm-skill-id-lint, check:empty-changeset, check:changeset-no-major, check:adr-0087-registration, check:closing-keyword-parity, check:published-files, check:pm-governed-merges all measured green. NOT MEASURED, 1: check:dual-build-cjs-loads (exit 3 PREREQUISITE NOT MET — it needs every one of the 129 packages built; CI's). PR check-runs on 71213196: in_progress at report time.", "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm", "mcp_calls": "0 — no MCP GitHub calls", "api_writes": "1 this round — relay stroke as objectstack-fleet[bot]: POST /repos/objectstack-ai/objectstack/issues/28582/comments (this delta via post-stamped.mjs). Plus 1 `git push` (71213196) — git, not REST. Cumulative: 4 relay writes (pr_create, report, delta, delta 2), 4 pushes. PR body untouched (no PATCH).", "deviations": [ "Round-1 cuts with a docs-page-only home that remain cut (listed in summary) — restoring them is a ceiling question for the maintainer on this Tier H PR; headroom today is 6 tokens (≈24 bytes)." ], "open_questions": [], "out_of_scope_findings": [ "carrier: none · noted, not filed (convenience gap): no `os` subcommand prints an MCP server's tools with their `mcpToolDigest`; an author without code boots once with a placeholder pin to read the served digests. Dedupe words: mcpToolDigest CLI, tools/list digest, computeMcpToolsSnapshot command." ] }objectstack-fleet commentedon Nov 1, 2026
epic:#27293#1 · sunhaolin · session_017xRBcVBKAFk1ntXSjvPt7U
MERGED → PR #28597 through the merge queue (merge commit
28f2e99b8, queued byos-zhuang) · 2026-11-01T10:23Z. Closedcompletedby itsFixes #28582.pm:dispatchedis removed in this act;pm:epicis kept.skills/objectstack-automation/references/integration-recipes.mdnow teachesproviderConfig.toolsSnapshoton the MCP recipe: the pin, its digests, and the two mismatch outcomes split on whether the instance's credential reached the server. The connectors page's failure-mode row agrees with it. This closes the Skills-docs follow-up PR #28515 owed. The two optional nits in the seat record 6555464359 (64 lowercase hex; theDELETErevokes clause that eval 1 names) were not taken.