Skip to content

Commit 50c4ec0

Browse files
feat(devx): check:package-naming — packages/services/ packages are service-NAME after their directory, and the plugin- prefix is frozen at ten (#29710) (#29739)
<!-- claude-projects-attribution: {"github_login":"os-warren"} --> _Requested by **Warren** · [project thread](https://claude.ai/code/project/chan_01U5RdnAAmkSQmZbqh6FtqZ8?thread=cmsg_01U5RdnAAmkSQmZbqh6FtqZ8QModZH3Kxarp5xssNiWbVr)_ Fixes #29710 Clause-②: no Metadata-protocol: none ## 维护者速读 - 改了什么:新增门禁 `check:package-naming`。`packages/services/` 下每个包必须叫 `@objectstack/service-名字` 且目录名与包名一致;`@objectstack/plugin-*` 这组名字冻结在今天的十个,新包再用 `plugin-` 前缀直接红。 - 为什么改:Warren 2026-11-03 的裁决「应该用 service-*,包括如何制定仓库规则,避免类似的问题」「plugin- 太笼统,是不是建议逐渐退役这个名字」。推送通道差点按 ADR-0012 叫 `plugin-notification-push`;包名一旦发布就收不回。 - 风险与回滚:只读 `package.json`,不构建、不联网、亚秒级;今天的树全绿。不改名、不挪任何现有包。回滚即撤 PR。 - 先看:① `scripts/check-package-naming.mjs` 的 `judge()` 与 `FROZEN_PLUGIN_NAMES`;② `.github/workflows/lint.yml` 新增的一步(Tier H);③ 同文件 self-test 的两个 fixture 用例。 - 两分钟验证:`pnpm check:package-naming`,应见 self-test 15 例通过,随后一行 ✓,写明 129 个包、18 个 service、恰好 10 个冻结名。 - 需要你做的:审阅并落地(含 `.github/workflows/lint.yml`,Tier H 需维护者合并)。 ## What changes - **New gate `scripts/check-package-naming.mjs`**, on `scripts/workspace-enumerator.mjs` (the one parse of `pnpm-workspace.yaml`). Two rules over every workspace manifest: - `[services-prefix]` / `[dir-mismatch]`: every package whose directory sits directly under `packages/services/` is named `@objectstack/service-NAME`, and NAME with the prefix is its directory basename. - `[plugin-prefix]` / `[stale-row]`: the set of `@objectstack/plugin-*` names is a shrink-only ratchet, `FROZEN_PLUGIN_NAMES`, frozen at the ten the tree carries today: `approvals`, `audit`, `auth`, `dev`, `email`, `hono-server`, `pinyin-search`, `security`, `sharing`, `webhooks`. A new name reds with the remedy "name it by its kind" (`service-`, `connector-`, `driver-`, `embedder-`, `knowledge-`). Growing the set is refused outright, not offered as a remedy. A frozen name the tree no longer carries reds too, so the set can only shrink. - A lit control (at least 50 packages, `@objectstack/spec` present, at least one member under `packages/services/`) makes an enumeration that stops reading the tree exit 2, never 0. `--root DIR` judges another checkout. - `--self-test` arm: 15 table-driven cases with the sibling battery floor (pattern of `check-skill-top-level-keys.mjs`), including two that build a real fixture workspace on disk and judge it through the enumerator. - **Wiring**: `check:package-naming` in the root `package.json` (`--self-test` then the run), and one step in `.github/workflows/lint.yml` right after `check:workspace-manifest-cycles`, same shape (`continue-on-error: true`, rationale comment pointing at the header). There is no `check:all` aggregator in this repo, so the workflow step is the only CI wiring; the seat ruled option A, and that makes this PR Tier H. - **Scope, stated**: the 18 `@object-ui/plugin-*` packages under `ui/packages/` are a separate scope and are NOT in the frozen set (seat ruling). A `@objectstack/service-*` package outside `packages/services/` is not judged (0 today). No existing package is renamed or moved. - No changeset: the diff is `scripts/**`, the root manifest and a workflow, none of which publishes (`skip-changeset`). ## Tests - `node scripts/check-package-naming.mjs --self-test`: exit 0, `✓ check-package-naming self-test: 15 cases pass.` - `node scripts/check-package-naming.mjs` on this branch: exit 0, `✓ check-package-naming: 129 workspace package(s); all 18 in packages/services/ are @objectstack/service-* named after their directory; the @objectstack/plugin-* set is exactly the 10 frozen names.` - Red-first on the real tree (fixtures written into the worktree, then removed; `git status` clean afterwards): `packages/services/plugin-x` named `@objectstack/plugin-x` plus an eleventh `packages/plugins/plugin-notification-push` gave exit 1 with three findings: `[services-prefix] packages/services/plugin-x`, `[plugin-prefix] packages/plugins/plugin-notification-push`, `[plugin-prefix] packages/services/plugin-x`. - #29041's `service-push` branch does not exist yet (no branch or PR for it on the remote at the time of writing), so the gate has not been run on it: NOT MEASURED. `@objectstack/service-push` in `packages/services/service-push` is the shape the gate accepts; `--root` lets the seat run it on that checkout. ## Acceptance notes - The frozen set is meant to equal the ten named in #29709's rule text; that card runs in parallel, and the seat holds the two in step. - `check:entry-guard` caught the first draft calling `main()` at top level while exporting `judge`/`readRows`; the second commit puts the dispatch behind `isEntrypoint` from `invoked-as.mjs`. ## Verification <details><summary>Local gate union on the final head</summary> Head `4d2af80c` (rebased on origin/main `9b4fa6cc`). `node scripts/pm/dispatch-gates.mjs --commands` derived 65 families from the 3 changed paths; each was run with its exit code captured before any pipe, then reconciled: ```text node scripts/check-closing-keyword-parity.mjs :: exit 0 node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0 node scripts/check-comment-mask-corpus.mjs :: exit 0 node scripts/check-declaration-mirrors.mjs :: exit 0 node scripts/check-declaration-mirrors.mjs --self-test :: exit 0 node scripts/check-dts-emitted.mjs --self-test :: exit 0 node scripts/check-merged-branch-reaper-outcome.mjs :: exit 0 node scripts/check-merged-branch-reaper-outcome.mjs --self-test :: exit 0 node scripts/check-self-test-wired.mjs :: exit 0 node scripts/check-self-test-wired.mjs --self-test :: exit 0 node scripts/check-self-test-workflow-commands.mjs :: exit 0 node scripts/check-self-test-workflow-commands.mjs --self-test :: exit 0 node scripts/check-step-collectors.mjs :: exit 0 node scripts/check-step-collectors.mjs --self-test :: exit 0 node scripts/check-whole-set-label-write.mjs :: exit 0 node scripts/check-whole-set-label-write.mjs --self-test :: exit 0 node scripts/ci/assert-turbo-remote-cache.mjs --self-test :: exit 0 node scripts/ci/plan-test-core-shards.mjs --self-test :: exit 0 node scripts/ci/prune-turbo-cache.mjs --self-test :: exit 0 node scripts/ci/scheduled-full-run.mjs --self-test :: exit 0 node scripts/docs-audit/check-drift-comment.mjs :: exit 0 node scripts/pm/bare-root-worklist.mjs --self-test :: exit 0 node scripts/pm/ci-failure.mjs --self-test :: exit 0 pnpm check:agent-test-spelling :: exit 0 pnpm check:aggregator-roster :: exit 0 pnpm check:bash32-floor :: exit 0 pnpm check:ci-filter-parity :: exit 0 pnpm check:cli-command-ids :: exit 0 pnpm check:cross-package-test-inputs :: exit 0 pnpm check:declared-population-live :: exit 0 pnpm check:driver-memory-census :: exit 0 pnpm check:dts-closure :: exit 0 pnpm check:dual-build-cjs-loads :: exit 0 pnpm check:entry-guard :: exit 0 pnpm check:gitlink-declared :: exit 0 pnpm check:lean-entry-closure :: exit 0 pnpm check:manifest-repository-directory :: exit 0 pnpm check:merge-driver :: exit 0 pnpm check:node-version :: exit 0 pnpm check:nul-bytes :: exit 0 pnpm check:package-naming :: exit 0 pnpm check:parse-guard :: exit 0 pnpm check:pm-expected-skips :: exit 0 pnpm check:pm-governed-merges :: exit 0 pnpm check:pm-post-stamped :: exit 0 pnpm check:pm-record-recognisers :: exit 0 pnpm check:pnpm-acquisition :: exit 0 pnpm check:pnpm-filter-targets :: exit 0 pnpm check:pnpm-flag-spellings :: exit 0 pnpm check:ratchet-remedy-authority :: exit 0 pnpm check:refd-timer-probe :: exit 0 pnpm check:required-contexts :: exit 0 pnpm check:scripts-symbol-anchors :: exit 0 pnpm check:select-gate-families :: exit 0 pnpm check:shard-attestation :: exit 0 pnpm check:sourcemap-no-sources-content :: exit 0 pnpm check:stall-guard-budget :: exit 0 pnpm check:stall-guard-headroom :: exit 0 pnpm check:turbo-task-graph :: exit 0 pnpm check:type-check-coverage :: exit 0 pnpm check:type-check-debt :: exit 0 pnpm check:watch-hint-literal :: exit 0 pnpm check:workflow-status-functions :: exit 0 pnpm check:workflow-step-name-quoting :: exit 0 pnpm check:pm-dispatch-gates :: exit 0 pnpm lint :: exit 0 ``` `dispatch-gates --ran`: `65 derived famil(ies) accounted for — 65 run, 0 NOT-MEASURED` (exit 0). `check:pm-dispatch-gates`: `1945 cases pass` (fast tier). Every family CI runs is read from this PR's check-runs. </details> ## Human Minimum - [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic. (not touched) - [x] 2. Every name I added uses the casing for its kind. - [x] 3. No formatter ran; `pnpm lint` passes. - [x] 4. One issue, one branch off an up-to-date `main`, one pull request. - [x] 5. A change that publishes carries a changeset, and both declaration lines are filled in here and in the changeset. (nothing publishes) - [x] 6. `packages/spec` touched: its generated artifacts are regenerated and committed. (not touched) - [x] 7. No hand edits to `content/docs/references/`, `packages/*/CHANGELOG.md` or `content/docs/releases/`. - [x] 8. Title, body and comments are in English. (except the Chinese maintainer summary the repo asks for) - [x] The *Before Submitting* list in CONTRIBUTING.md is done. --- _Generated by [Claude Code](https://claude.ai/code/session_01JQwxbXkaL8RZJzfDDK793u)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent ea4dcf9 commit 50c4ec0

3 files changed

Lines changed: 299 additions & 0 deletions

File tree

‎.github/workflows/lint.yml‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3988,6 +3988,15 @@ jobs:
39883988
continue-on-error: true
39893989
run: pnpm check:workspace-manifest-cycles
39903990

3991+
# Rationale: `scripts/check-package-naming.mjs` header (#29710). Every
3992+
# packages/services/ package is `@objectstack/service-NAME` after its
3993+
# directory, and the `@objectstack/plugin-*` set is frozen at ten. Reads
3994+
# manifests only; the `check:` key runs `--self-test` first.
3995+
- name: package names follow their kind and the plugin prefix is frozen
3996+
id: package-names-follow-their-kind
3997+
continue-on-error: true
3998+
run: pnpm check:package-naming
3999+
39914000
# Merged-result budget probe, wired by the card that wired the citation
39924001
# gate below (#18224). `node scripts/check-merged-result.mjs --self-test`
39934002
# IS the whole gate and is exactly what the root manifest registers as

‎package.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@
108108
"check:pnpm-flag-spellings": "node scripts/check-pnpm-flag-spellings.mjs --self-test && node scripts/check-pnpm-flag-spellings.mjs",
109109
"check:turbo-task-graph": "node scripts/check-turbo-task-graph.mjs --self-test && node scripts/check-turbo-task-graph.mjs",
110110
"check:workspace-manifest-cycles": "node scripts/check-workspace-manifest-cycles.mjs --self-test && node scripts/check-workspace-manifest-cycles.mjs",
111+
"check:package-naming": "node scripts/check-package-naming.mjs --self-test && node scripts/check-package-naming.mjs",
111112
"check:adr-anchors": "node scripts/check-adr-anchors.mjs --self-test && node scripts/check-adr-anchors.mjs",
112113
"check:adr-links": "node scripts/check-adr-links.mjs --self-test && node scripts/check-adr-links.mjs",
113114
"adr:index": "node scripts/adr-index.mjs",

0 commit comments

Comments
 (0)