Skip to content

docs(skills): name the installation-wide uniques stop for a self-hosted os deploy - #31428

Merged
os-zhuang merged 1 commit into
mainfrom
claude/project-thread-4cicu8
Nov 8, 2026
Merged

os-zhuang merged 1 commit into
mainfrom
claude/project-thread-4cicu8

Conversation

@os-project-manager

Copy link
Copy Markdown
Collaborator

Requested by Leehom · project thread

Part of #31338

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:平台技能 operations.md 中 use-runtime 目标的退出码 1 段,在「安装被拒」一项里补上全局唯一约束停止:约束确属全平台时用 --confirm-global-uniques 重跑,否则改成 unique: 'organization'。
  • 为什么改:PR fix(cli): os deploy takes --confirm-global-uniques on a self-hosted runtime #31369(cli: a use-runtime os deploy stopped on installation-wide uniques prints os deploy --confirm-global-uniques, a flag os deploy does not declare #31338)已让 os deploy 在自托管运行时接受 --confirm-global-uniques,但技能只教了两个升级确认,agent 读技能时不知道这个停止和开关。
  • 风险与回滚:纯技能文字;token 棘轮先删同文件两处重复(-67 字节),余额 +19 tokens 按常设裁定 6513306068 抬高该行(3375 → 3394);发版 @objectstack/skills patch;回滚即 revert。
  • 两分钟验证:node scripts/check-skills-token-ratchet.mjs(3394 / 3394);对照 packages/cli/src/commands/package/install.ts L445-L456 的停止文案。
  • 需要你做的:Tier H(skills/**),合并前需席位契约复核与 os-zhuang 或 hotlong 批准。

What changes

skills/objectstack-platform/references/operations.md, the use-runtime target paragraph (added by #31335, merged). Its install-refusal clause listed the access and schema upgrade confirmations only. It now also names the installation-wide uniques stop (UNIQUE_SCOPE_CONFIRMATION_REQUIRED, ADR-0120 D5e), whose printed retry is os deploy --confirm-global-uniques, and the stop's other way on:

-… an install refusal (rerun with the `--confirm-access-upgrade` / `--confirm-upgrade <token>` it printed); installed but not loaded …
+… an install refusal (rerun with the `--confirm-access-upgrade` / `--confirm-upgrade <token>` it printed, or `--confirm-global-uniques` if its installation-wide `unique` constraints are meant platform-wide, else set them `unique: 'organization'`); installed but not loaded …

Source on main (405a78ea): packages/cli/src/commands/package/install.ts L445-L456 (the stop prints ${retry} --confirm-global-uniques and "…or edit the app's metadata to unique: 'organization' and rebuild"); packages/cli/src/commands/deploy.ts L100 (CONFIRMATION_FLAGS) and L160 (the flag, self-hosted target only). os deploy rebuilds, so "and rebuild" is the deploy itself.

Why

PR #31369's acceptance notes left this line to the skills lane ("Not edited here … the line it needs is in the report's out_of_scope_findings"). Without it, an agent reading the platform skill meets the stop with no taught way on.

Token readings (scripts/check-skills-token-ratchet.mjs, tokens = ceil(bytes / 4))

File main e6a0b72a90 This PR Ceiling
skills/objectstack-platform/references/operations.md 13500 B = 3375 13574 B = 3394 3375 → 3394

Deletions, each with its surviving home (-67 bytes):

  1. Health & observability, Logs bullet: the example new ObjectKernel({ logger: { level: 'info', format: 'json' } }) becomes "(new ObjectKernel({ logger }))" (-36 B). Home of the shape: references/plugin-development.md § ObjectKernel Configuration (logger: { level: 'info', format: 'json' }). The bullet's own fact (a kernel construction option, not a defineStack key) stays.
  2. Metrics bullet: "(per-plugin startup durations)" (-31 B). Home: references/plugin-development.md § Health Monitoring, kernel.getPluginMetrics(); // Map<name, startup ms>.

No eval pins either (skills/objectstack-platform/evals/*.json swept for getPluginMetrics, logger, format).

Added: +141 B. Net +74 B → 3394 tokens; headroom was 0, so the remainder, +19 measured, raises that one row, pinned at the measurement, under the standing maintainer ruling 2026-10-27, verbatim and untranslated: 「A:先削重复,余额按实测提高」 (ruling record 6513306068 on #27847). No rewrap: every untouched line is byte-identical.

Not edited

Verification

Head da7c715974 (one commit on main e6a0b72a90). node scripts/pm/dispatch-gates.mjs --commands derived 62 commands for the 3 paths: 57 × exit 0; 5 NOT MEASURED (exit 3, prerequisite: a build): check:dts-closure, check:dual-build-cjs-loads, check:lean-entry-closure, check:sourcemap-no-sources-content read every package's dist, and no package is touched; @objectstack/lint check:doc-formula-expressions needs the formula and lint builds and this diff adds no formula. Those go to CI. Per-command record: project file pm-orders/server/31338-skills-gates-ran.txt.

  • node scripts/check-skills-token-ratchet.mjs: exit 0, 3394 / 3394; --self-test exit 0.
  • node scripts/check-empty-changeset.mjs --base origin/main, check-changeset-no-major.mjs: exit 0.
  • node scripts/check-commit-card-trailers.mjs --range origin/main..HEAD: exit 0.

Changeset .changeset/31338-platform-skill-global-uniques-stop.md: @objectstack/skills patch, both declaration lines.

Human Minimum

  • 1. Schemas start as Zod; packages/spec holds no runtime logic. (not touched)
  • 2. Every name I added uses the casing for its kind. (none added)
  • 3. No formatter ran; pnpm lint passes. (no lintable source touched; CI)
  • 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.
  • 6. packages/spec touched: n/a.
  • 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 follows the project's PR convention)

Generated by Claude Code

…ed os deploy

The platform skill's use-runtime exit-1 paragraph listed the access and
schema upgrade confirmations but not the installation-wide `unique`
constraints stop, whose printed retry is `os deploy
--confirm-global-uniques` (a flag os deploy now accepts). The install
refusal clause now names it and the alternative (`unique:
'organization'`). Paid by cutting two restatements homed in
references/plugin-development.md; the +19-token remainder raises the
operations.md ratchet row under the standing ruling 6513306068.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FEkQ5oBgusQkTutB9LsDed
@os-project-manager os-project-manager self-assigned this Nov 8, 2026
@github-actions github-actions Bot added the size/s label Nov 8, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor

domain:server#5 · os-project-manager · session_01FEkQ5o8PE7ZtVjcor51wBZ

Contract-review-claim: session_01FEkQ5o8PE7ZtVjcor51wBZ · head da7c715 · 2026-11-08T07:29Z

@github-actions github-actions Bot added documentation Improvements or additions to documentation tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface labels Nov 8, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor

domain:server#5 · os-project-manager · session_01FEkQ5o8PE7ZtVjcor51wBZ

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: da7c7159749060ad848c610c97cfadaf637c1a3a
Local-runs: probe — node scripts/pm/record-recognisers.mjs --template --paths skills/objectstack-platform/references/operations.md, run once to print this record's own shape; it reads no PR file and is no gate, build or test. Everything else was read from blobs (git show, git diff origin/main...pr/31428), the card, the PR body and the head's check-runs.
Scope: skills/objectstack-platform/references/operations.md + scripts/check-skills-token-ratchet.mjs

Inputs read: card #31338 (body, 3 comments: triage 6716400526, claim 6716849304, os-dev-report 6717349738); PR #31428 body and file list (3 files: the changeset, the ratchet row, operations.md); the net diff against main at the merge base e6a0b72a90; main 0647dabb (contains #31369's merge 405a78ea): packages/cli/src/commands/deploy.ts, packages/cli/src/commands/package/install.ts, packages/cloud-connection/src/marketplace-install-local-plugin.ts, packages/types/src/unique-scope-install-gate.ts, content/docs/deployment/cli.mdx, docs/adr/0120; the skill's references/plugin-development.md on the head (not in the diff, read as the home of the two cuts); ruling record 6513306068 on #27847; /mnt/project-files/pm-orders/server/31338-skills-gates-ran.txt; the 36 check-runs on the head.

① Derived judgments

What an agent following the head's paragraph does at the use-runtime exit-1 stop, each judged against the CLI on main:

  • Flag spelling — right. The skill writes --confirm-global-uniques bare, no token. deploy.ts L160 declares it Flags.boolean and L100 lists it in CONFIRMATION_FLAGS, so confirmationArgv forwards it as a switch; the two upgrade confirmations keep their TOKEN. The paragraph's "rerun with … --confirm-upgrade TOKEN it printed, or --confirm-global-uniques" keeps that distinction.
  • Exit code — right. The embedded PackageInstall prints the stop and this.exit(1) (install.ts L447-L456); deployToRuntime then sees outcome?.kind !== 'installed' and exits 1 itself (deploy.ts L358-L362). Exit 1, as the paragraph says.
  • Which stop — right. The runtime's gate is step 2b of install-local, placed AFTER if (dryRun) return this.answerUpgradeDryRun(...) (marketplace-install-local-plugin.ts L2716 then L2735-L2744), so a dry run never raises UNIQUE_SCOPE_CONFIRMATION_REQUIRED; it is the install step's refusal. The paragraph files it under "an install refusal", not under "a dry run refused" — the right stop.
  • The printed retry — right. deployToRuntime sets command.retryCommand = 'os deploy' (deploy.ts L342) and install.ts L453 prints ${retry} --confirm-global-uniques, so "it printed" names os deploy --confirm-global-uniques, which os deploy now accepts verbatim.
  • The alternative — right. install.ts L454 says "edit the app's metadata to unique: 'organization' and rebuild"; os deploy begins with the build (deploy.ts L329-L335), so the skill's "set them unique: 'organization'" with no "and rebuild" loses nothing. 'organization' is the ADR-0120 scope the CLI, cli.mdx L3545-L3546 and the spec (UniqueScopeSchema, boolean | 'global' | 'organization') all name.
  • "installation-wide unique constraints" — right, and deliberately wider than 'global'. The gate also reports the deprecated bare unique: true spelling (describeGlobalUniqueFinding), so naming the constraints by what they do rather than by one spelling matches what the stop lists.
  • Scope of the stop — not stated, not wrong. The gate fires only under the isolated tenancy posture (postureGatesGlobalUniques); the paragraph does not say so. An agent on a single or group runtime never meets it; one on isolated meets exactly the text taught. cli.mdx L3270-L3271 names the posture; the skill paragraph does not, which costs an agent nothing at the stop.
  • "(no --env)" — still right. With --env, or no runtime recorded, every confirmation flag is refused before any build with exit 1 (deploy.ts L194-L200). That cloud-side refusal is not in the cloud exit-1 paragraph; it is also not in this diff's claim (nit, ④).

② Semver level

.changeset/31338-platform-skill-global-uniques-stop.md: '@objectstack/skills': patch (the package at packages/skills/package.json), Clause-②: no, Metadata-protocol: none; the PR body carries the same two lines. Right on all three: the diff changes teaching text and a gate row only; no published schema, no metadata key, no CLI accept set moves (that widening was #31369's @objectstack/cli patch with Clause-②: yes, already on main). Same shape as the precedent .changeset/31235-platform-skill-use-runtime-deploy-exit.md (#31335). The changeset's one-paragraph account ("two ways on"; "os deploy already accepts the flag; this release only teaches it"; "two logger and metrics restatements … are cut") matches the tree.

③ Boundary flags

The dev's 5 NOT MEASURED gate families against the head's check-runs (read 2026-11-08 ~07:31Z; 36 check-runs, 0 failed, 14 in_progress):

  • check:dts-closure, check:dual-build-cjs-loads, check:sourcemap-no-sources-content, check:lean-entry-closure — all four live in ci.yml's Build Core job. On da7c715 Build Core is completed / success, and its job steps "Sweep the built closure for vanished declarations", "Every published require entry point actually loads", "No published source map embeds source text" and "The lean engine entry loads no forbidden or unlisted package" are each success. Measured green by CI. (check:dts-closure runs again in Type Check · debt ledger and Type Check · consumer gates: in_progress.)
  • @objectstack/lint check:doc-formula-expressions — lint.yml Type Check · consumer gates, step "Check docs formula examples are valid CEL": in_progress at read, not yet a verdict. The diff adds no formula text, so nothing in it can turn that step.

The record file holds 62 rows, 57 × exit 0 and 5 × exit 3, the five above — matches the PR body's account. Complete and green at read: Build Core, Check PR Size, Governed Surface Queue Guard, PR-body guards, Dogfood Regression Gate, Test UI, Auto Label, filter. Still running: Check Changeset, the eight Lint · lanes (the ratchet gate's own CI run is among them), the four Type Check · lanes, Live E2E UI, Plan Test Core shards. Landing waits on those; none has turned red.

The ratchet raise 3375 → 3394, against ruling record 6513306068 (letter B, part 2): the ruling makes the 2026-10-27 standing ruling 「A:先削重复,余额按实测提高」 the gate-recognised path for hand-authored references/**: a PR whose diff shows deletion of restatement in the same file and whose body quotes that ruling or the record may move the row by the measured remainder, pinned AT the measurement, with no per-card ruling; "the seat record checks the quote". Checked here:

  • Population: skills/objectstack-platform/references/operations.md is hand-authored teaching text — in the ruling's class.
  • Deletion in the same file, visible in the diff: two hunks, −36 B (the Logs bullet's { level: 'info', format: 'json' } example, reduced to new ObjectKernel({ logger })) and −31 B (the Metrics bullet's "(per-plugin startup durations)"), measured from the two blobs. Both are restatements, each homed: the logger shape at plugin-development.md § ObjectKernel Configuration (L38-L52, level: 'info', format: 'json'), the startup durations at § Health Monitoring (L338, getPluginMetrics(); // Map(name, startup ms)). The bullets' own facts survive: logger is a kernel-construction option and not a defineStack key; metrics are getPluginMetrics() + checkAllPluginsHealth(), no metrics service, no @objectstack/plugin-prometheus. No other file in the skill repeats the cut words (grep of skills/objectstack-platform on the head: the only hit for format: 'json' is the plugin-development.md home; none for "startup durations").
  • Quote: the PR body and the row comment both carry the ruling's words verbatim and the record id.
  • Measurement: 13500 B → 13574 B (+141 added, −67 cut, +74 net); ceil(13500/4) = 3375 exactly, so headroom was 0; ceil(13574/4) = 3394; the row is pinned at 3394, the remainder +19 as stated. Reproduced from the blobs by the header's wc -c convention, not by running the script.
  • docs(skills): document permission-set assignment, and name permissions as its defineStack key #10402 principle (no growth for a small feature): +19 tokens buy the one clause an agent at a shipped exit-1 stop had no taught way past; the restatement was cut first. Within the ruling. The raise is within 6513306068.

④ Design judgment

hits — skills/objectstack-platform/references/operations.md, the use-runtime paragraph, read sentence by sentence against the code it cites on main:

  • "A use-runtime target (no --env) asks for no cloud login: build, dry-run plan, install, live on hotLoaded." Unchanged; still the four steps of deployToRuntime.
  • "Exit 1: a failed build; a dry run refused, unserved (no install-local) or ignored (an older runtime installed: upgrade it);" Unchanged; matches L329-L350.
  • "an install refusal (rerun with the --confirm-access-upgrade / --confirm-upgrade TOKEN it printed, or --confirm-global-uniques if its installation-wide unique constraints are meant platform-wide, else set them unique: 'organization');" — the changed clause. Agrees with install.ts L445-L456 (the stop, its two ways on, their order) and with deploy.ts L100/L160 (the flag, boolean, forwarded). "its" is the package's; "them" are the constraints the stop lists. The confirmation is guarded by a condition, not offered as the default.
  • "installed but not loaded (live after a restart)." Unchanged; matches L363-L369.

Could an AI follow it into confirming by reflex? The clause makes confirmation conditional on the constraints being "meant platform-wide" and gives the per-organization rewrite as the else-branch, and at the moment of action the agent is reading the stop itself, which prints GLOBAL_UNIQUE_ISOLATED_PRESCRIPTION verbatim (why an installation-wide unique under isolated crosses customers; the three examples of a genuinely platform-wide key; option (b) rewrite). The skill adds no pressure toward (a). No must-fix.

Findings, graded:

  1. nit — the clause leads with the confirmation and carries none of ADR-0120's lean ("a 'global' unique on an app business object is almost always meant company-wide, not cross-customer"; platform-wide = infra/dedup keys, hostnames, external ids). It mirrors the CLI's own order (confirm line first, "…or edit" second) and the stop's printed prescription supplies the lean, so correctness and the contract are unaffected; a later edit at zero headroom could trade words for "only for infra/dedup keys; an app rule is per-organization".
  2. nit — os deploy --confirm-global-uniques is a boolean and confirms every pending index at once (the CLI never sends the body's per-id list), so a mixed set (some genuinely platform-wide, some per-organization) is handled by rewriting the per-organization ones and rerunning; the clause's "if … else" does not say mixed. The same holds for os package install; not a claim this diff makes false.
  3. nit — skills/objectstack-platform/evals/config-plugins-ops.json case 21's expected_output still names only --confirm-access-upgrade as a refusal's confirmation. Pre-existing (named in docs: teach os mcp connect and the use-runtime deploy target in the remaining pages #31335's "Other sites found" and this PR's "Not edited"); not a regression of this diff and no eval pins the cut text.
  4. nit — the cloud exit-1 paragraph does not name the exit-1 refusal of any confirmation flag when the target is ObjectOS Cloud (deploy.ts L194-L200); outside this diff's claim.

Implementing file in the diff — scripts/check-skills-token-ratchet.mjs: the one row moves to 3394 with a comment in the file's established form (what was added, what was cut and where it is homed, the byte arithmetic, the ruling verbatim and its record id). The number agrees with the blob (③). No other row, the header or the counting convention changes. No finding.

Read, not reviewed: references/plugin-development.md is not in the diff; both homes named for the cuts exist on the head at the sections cited.

Implemented-by: claude/project-thread-4cicu8
Reviewed-by: session_01FEkQ5o8PE7ZtVjcor51wBZ

VERDICT: PASS


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor

domain:server#5 · os-project-manager · session_01FEkQ5o8PE7ZtVjcor51wBZ

席位意见:接受。平台技能的运维参考里,os deploy 在安装步骤因「全实例唯一约束」退出 1 的那一段,现在点出这条停止和 --confirm-global-uniques:确实要全平台唯一就带上它重跑,否则改成 unique: 'organization'。契约复审 PASS,无必改项。改动在 skills/**,需要审批人批准后由席位落地。

席位核对 — ACCEPT · domain:server#5 · Head-sha da7c7159749060ad848c610c97cfadaf637c1a3a · 2026-11-08T07:41Z

The maintainer's standing authorisation for landing reviewed PRs, verbatim: 「按照 pm-dispatch 规则复核过的都授权」.

  • Shape: 3 files (+27 / −5), read from the diff:

    • one paragraph in skills/objectstack-platform/references/operations.md, with two restatements homed in references/plugin-development.md cut from it;
    • the token-ratchet row 3375 → 3394 under ruling 6513306068;
    • one changeset (@objectstack/skills patch).

    Clause-②: no, Metadata-protocol: none. It follows PR fix(cli): os deploy takes --confirm-global-uniques on a self-hosted runtime #31369 (cli: a use-runtime os deploy stopped on installation-wide uniques prints os deploy --confirm-global-uniques, a flag os deploy does not declare #31338).

  • Review: CONTRACT_REVIEW_TIER (fable), by a reviewer outside the dev's session: PASS 6718806788 on this head, with no must-fix or should-fix. Its four nits are accepted as they stand, because a prose fix would move the head and the ratchet has no headroom left:

    • the lean toward the per-organization scope;
    • a mixed pending set;
    • the eval case that names one flag;
    • the Cloud refusal line.

    Ruling-ref: 2026-11-07T16:00Z 「你有 fable ,车道契约复审可以自己做」.

  • Gates: head check-runs are 29 success and 13 skipped, with none red or pending. check-expected-skips: OK (exit 0). check-governed-merges: GOVERNED, skills/** ×1, Tier H, 32 changed lines. The dev's derived gates: 57 of 62 exit 0. The 5 NOT MEASURED dist and doc-formula families are answered green by Build Core and Type Check · consumer gates on this head.

  • Landing: Tier H. pm:awaiting-merge, with reviewers os-zhuang and hotlong requested. It stays draft until an approver approves. Then the seat readies it and turns on auto-merge, or the maintainer merges it.


Generated by Claude Code

@objectstack-fleet objectstack-fleet Bot added the pm:awaiting-merge PR only: landing waits on the maintainer's own review and merge (SKILL.md 复核 ②); never on an issue label Nov 8, 2026
@os-zhuang
os-zhuang marked this pull request as ready for review November 8, 2026 07:43
@os-zhuang
os-zhuang added this pull request to the merge queue Nov 8, 2026
Merged via the queue into main with commit 3d73c1d Nov 8, 2026
48 checks passed
@os-zhuang
os-zhuang deleted the claude/project-thread-4cicu8 branch November 8, 2026 08:03
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 pm:awaiting-merge PR only: landing waits on the maintainer's own review and merge (SKILL.md 复核 ②); never on an issue size/s tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants