Skip to content

chore(deps): upgrade @objectstack/* to 17.7.0 - #2008

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/wizardly-heisenberg-pxsilt
Oct 7, 2026
Merged

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/wizardly-heisenberg-pxsilt

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Description

Upgrade HotCRM from @objectstack/* 17.6.0 to 17.7.0, following the official upgrade guide (/docs/upgrading, Moving the dependency pins) and the 17.7.0 release page's upgrade checklist. The page says 17.6.0 → 17.7.0 had not been exercised on any application; this PR is that exercise, on this app, in place and fresh.

The upgrade turned pnpm verify red in three places. Each one is a 17.7.0 change the release notes name, and each is answered here at the place it reached this app:

  1. os validate refused three action ids on the lead page's Tasks related list (action-name-undefined).
  2. lint:i18n-gate reported 108 i18n/missing-flow keys. The 17.7.0 console now reads screen-flow translations, and os lint reports the missing ones.
  3. Eleven test files:
    • nine harnesses wrote to sys_user without registering it, and the engine now refuses unregistered names (objectstack#21545);
    • two assertions expected 403 where a write to an unreadable row now answers 404 RECORD_NOT_FOUND (objectstack#21812);
    • one stub lacked the header() the 17.7.0 share-link route calls.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Code refactoring
  • Performance improvement
  • CI/CD update

Related Issues

Fixes #1210
Fixes #1975
Related to #1836 (the mailing-address conversion now has a 17.7.0 route) · #1992 (its Restart-when: is met once this lands: the installed @objectstack/objectql 17.7.0 CHANGELOG.md contains #21646)

Changes Made

  • Pins. All 21 @objectstack/* packages move 17.6.0 → 17.7.0, exact. specVersion and engines.protocol move to ^17.7.0 in the manifest and the stack config. The lockfile was regenerated:
    • 706 → 704 packages;
    • 54 @objectstack/* / create-objectstack keys moved 1:1;
    • @noble/ciphers and jose left the tree;
    • no third-party package changed version.
  • Screen-flow translations (src/sales/translations/{zh-CN,es-ES,ja-JP}/app.ts): a new flows section covers the 7 screen flows, 36 keys × 3 locales.
  • lead_detail.page.ts: three action ids removed. crm_task defines no action, so they never drew anything. The platform's own New and View all stay.
  • scripts/backfill-contact-mailing-address.ts: a new --unmapped FILE option takes the JSON from objectstack migrate unmapped-columns --object crm_contact --json, because no REST read returns an orphaned column on 17.7.0. Without the flag, the script behaves as before.
  • Tests:
    • a new test/helpers/identity-objects.ts registers the identity objects plugin-auth registers in a real boot, mounted in nine harnesses;
    • two reach tests expect RECORD_NOT_FOUND for writes to unreadable rows; the writes are still refused and still unwritten;
    • the share-link stub gains header();
    • no assertion was loosened and no test was skipped.
  • Pin claims re-scoped (AGENTS.md Platform Upgrades step 5):
    • What's new (3 locales) and docs/STATUS.md now name 17.7.0;
    • five comments that read as "17.6.0 is the pin" now date themselves;
    • "measured on 17.6.0" claims stay as written.
  • Changeset: .changeset/objectstack-17-7-0.md (minor).

Testing

  • pnpm verify green: os-verify-lock: VERDICT command-exit 0.
    • Validation passed (18 Objects, 359 Fields)
    • lint 1 warning(s), 18 suggestion(s)
    • 0 i18n/missing-* issues
    • source hygiene clean, source token ratchet clean
    • Build complete
    • Test Files 177 passed (177), Tests 3797 passed | 1 skipped
  • os migrate meta --from 17: 12 mechanical edits, all the decision-node mode: 'inclusive' the 17.6.0 upgrade already reviewed and left unwritten. None of 17.7.0's new conversions touches this app.
  • Exercised in place on a database HotCRM created, seeded and wrote to on 17.6.0: one account, one lead, one case, and an opportunity whose $150,000 amount opened an approval request.
    • os migrate meta --stored: 0 stored rows, so it attests nothing here.
    • os migrate audit-metadata-bodies: nothing to rewrite.
    • os migrate plan: in sync.
    • The 17.7.0 boot logged 0 errors.
  • Browser pass, 38 steps, all passing (Playwright + Chromium):
    • In place, en (21 steps):
      • the 17.6.0 records open;
      • the approval request opened on 17.6.0 was decided on 17.7.0 by an admin override; REST reads back status: approved and approval_status: approved;
      • an account created in the UI opened its approval;
      • the Escalate Case screen flow ran and the case reads Escalated;
      • the approvals inbox shows the 17.6.0 requests;
      • two reports render;
      • the executive, sales and service dashboards draw chart marks (DOM probe);
      • the lead page's Tasks list shows no refusal notice.
    • In place, zh-CN (9 steps): 升级工单 / 关闭工单 / 安排跟进 / 转化线索 / 生成报价单 / 批量加入成员 render Chinese titles and field labels, and the discount label reads 折扣 % (≤ 60).
    • Fresh 17.7.0 boot (8 steps):
      • an anonymous Web-to-Lead submission created its lead, so sharing.enabled: true holds on 17.7.0;
      • the Web-to-Case form opens anonymously;
      • first sign-up works, the seeded dashboard draws, and the opportunity and campaign lists are seeded.
  • Mailing-address conversion on 17.7.0, run against a contact whose orphaned mailing_street column held a value:
    • the REST read carried no mailing_* key;
    • os migrate unmapped-columns read the value;
    • --unmapped … --apply converted 1/1, and the address read back;
    • a rerun reported it already converted.

Screenshots

The 38 step screenshots, with before/after zh-CN dialogs, were taken in the session that ran this upgrade and shared with the maintainer there. They are not committed.

Checklist

  • I have added a changeset (pnpm changeset) — required on every PR, or the skip-changeset label is applied
  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings — lint reports 1 warning: page:card on Sales Home has a description the card does not declare. That is a long-known gap recorded in home.page.ts, not touched here.
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published (@objectstack/* 17.7.0 is on npm latest)

Additional Notes

  • Platform limitation, recorded and not worked around: select-option labels and screen descriptions on a screen flow are not translatable keys (FLOW_SCREEN_FIELD_NO_OPTIONS), so they stay as authored.
  • The first user's sign-up takes about 30–45 s on a freshly seeded database, measured as 34 s on 17.7.0 and about 31 s on 17.6.0 with the same procedure. This is not a change in this release.
  • Not exercised: the checklist's flow-secret rotation. The billing-handoff flows carry a signingSecret only when the build sets HOTCRM_BILLING_SIGNING_SECRET, and no run here set it.

🤖 Generated with Claude Code

https://claude.ai/code/session_01ER8ntXZhYebyQ66aXWdjfT

Move all 21 @objectstack/* dependencies 17.6.0 -> 17.7.0 together, with
specVersion and engines.protocol at ^17.7.0 (still protocol 17), and
regenerate pnpm-lock.yaml (706 -> 704 packages; 54 @objectstack keys moved
1:1; @noble/ciphers and jose left the tree; no third-party version moved).

Adopt what 17.7.0 changes for this app, per its release page and upgrade
checklist:

- translations: the 17.7.0 console's flow runner reads the `flows` group
  (liveness `live`), and `os lint` reports 108 i18n/missing-flow keys.
  Translate the seven screen flows in zh-CN, es-ES and ja-JP; the discount
  label interpolates QUOTE_DISCOUNT_CEILING (#1711). Fixes #1210, #1975.
- pages: drop the lead page Tasks list's `new_task` / `edit` / `complete`
  action ids. crm_task defines no action, and 17.7.0's
  action-name-undefined rule refuses them.
- scripts: the mailing-address backfill (#1836) takes `--unmapped FILE`
  from `os migrate unmapped-columns`, because 17.7.0 serves declared
  fields only and no REST read returns an orphaned column.
- tests: register the platform identity objects in nine harnesses (the
  engine refuses unregistered names, objectstack#21545); expect
  RECORD_NOT_FOUND for writes to unreadable rows (objectstack#21812); give
  the share-link stub the header() the 17.7.0 route calls.
- docs: What's new and docs/STATUS.md name 17.7.0; five comments that
  called 17.6.0 the pin now date themselves.

Exercised in place on a database HotCRM created on 17.6.0 (migrate meta
--stored: 0 rows; audit-metadata-bodies: nothing; plan: in sync; boot: 0
errors; a 17.6.0 approval decided on 17.7.0), and on a fresh 17.7.0 boot,
with a 38-step browser pass in en and zh-CN.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ER8ntXZhYebyQ66aXWdjfT
@vercel

vercel Bot commented Oct 7, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
hotcrm Ignored Ignored Oct 7, 2026 4:23am UTC

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation ci/cd CI plumbing and the verification pipeline dependencies Dependency bumps and lockfile changes metadata Declarative metadata — schema, security posture, UI surfaces configuration Build and app configuration files backend Server-side behaviour — hooks, flows, actions labels Oct 7, 2026
@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 7, 2026 12:17
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 7, 2026
Merged via the queue into main with commit c967803 Oct 7, 2026
11 checks passed
akarma-synetal pushed a commit to akarma-synetal/framework that referenced this pull request Oct 9, 2026
…tions — no app hooks, flows, approvals or notifications on the first sign-up (objectstack-ai#22069)

Fixes objectstack-ai#22067
Clause-②: no

## What changed

`claimSeedOwnership` hands every seeded row to the first platform admin.
Its one write, `reown` (a predicate write per unowned shape, paged only
when the engine refuses it for the per-row hook ceiling), now runs with
`{ isSystem: true, skipAutomations: true }` instead of a bare `{
isSystem: true }`. This is triage's ruling on the card (comment
6035454999), verbatim: "Run `reown` with `{ isSystem: true,
skipAutomations: true }`. This is the seed's own principle
(`engine.ts:5413`: seed loads end-state data, not user events), carried
to the attribution write that completes the seed." The page read
(`readPage`) is unchanged.

| file | change |
| --- | --- |
| `packages/plugins/plugin-security/src/claim-seed-ownership.ts` |
`CLAIM_WRITE_CTX`, used by `reown` only; the header says why, and which
hooks still run |
| `packages/plugins/plugin-security/src/claim-seed-ownership.test.ts` |
every `update` call (refused whole-set attempts, fallback pages, the
closing whole-set write) carries exactly `{ isSystem: true,
skipAutomations: true }` |
|
`packages/plugins/plugin-security/src/claim-seed-ownership-dispatch.pin.test.ts`
(new) | real `ObjectQL` over `SqlDriver`: what the flag reaches, and the
per-row hook ceiling |
|
`packages/qa/dogfood/test/seed-ownership-claim-dispatch.dogfood.test.ts`
(new) | booted app, first sign-up over REST: no automation in the claim
window; audit rows and sharing grants still land |
| `.changeset/22067-seed-claim-skip-automations.md` | `patch` for
`@objectstack/plugin-security`, with the line that app hooks no longer
fire for the seed ownership claim |

No `packages/objectql` change, the claim stays inside the request, and
no narrower flag was added.

## Latency A/B, built from source

Example: `examples/app-showcase`, the in-repo example that carries
metadata hooks and record-change flows on seeded objects. Each run:
`OS_SEED_ADMIN=0 objectstack dev --fresh --no-seed-admin --log-level
debug` on an empty database. The seed inserts 132 rows; 20 s after
`[Seeder] Seed loading complete`, the first user signs up with `POST
/api/v1/auth/sign-up/email` (curl `time_total`). The claim window runs
from `first user promoted to platform admin` to `handed 127 seeded
record(s) to platform admin` in the same request's log.

- **before**: this branch with `claim-seed-ownership.ts` restored to
`56bf27affb` (blob `78f3850d4a`), `@objectstack/plugin-security`
rebuilt; `dist/` verified to carry the base write (`multi: true,
context: SYSTEM_CTX9 }` x1, `CLAIM_WRITE_CTX` x0), then restored by blob
and rebuilt.
- **after**: this branch, rebuilt.
- One shared container for every run: absolute seconds are shared-box
readings, and the ratios are what carries.

| leg | sign-up wall time (3 runs) | claim window (3 runs) |
| --- | --- | --- |
| before | 1.540 / 1.670 / 1.675 s | 1.113 / 1.200 / 1.145 s |
| after | 0.947 / 0.954 / 1.016 s | 0.499 / 0.466 / 0.557 s |

Claim-window counts, identical in all three runs of each leg:

| in the claim window | before | after |
| --- | --- | --- |
| rows claimed | 127 (18 of 22 eligible objects) | 127 (18 of 22) |
| predicate writes (`Update operation starting`) | 44 | 44 |
| app hook bodies run (`[BodyRunner] hook fired`) | 10 | 0 |
| record-change flow dispatches (start condition evaluated) | 117 | 0 |
| flows run / approvals opened (`approval node suspended run`) | 2 / 2 |
0 / 0 |
| emails handed to the transport (`[LogTransport] would send email`) | 0
| 0 |
| metadata-bound dispatches skipped (`Skipping metadata-bound hook
(skipAutomations)`) | 0 | 416 |

- The showcase's flows gate on transitions (`status == "done" &&
previous.status != "done"` and the like), so an owner-only change
evaluates 117 start conditions and runs none of them, with one
exception. The draft `showcase_approver_bindings` flow has no condition,
so the claim ran it on both seeded `showcase_field_zoo` rows and opened
2 approval requests, each "resolved to no concrete approver". The
showcase wires no email transport, so 0 emails before and after.
- The 416 skipped dispatches: 35 app-hook dispatches
(`showcase_normalize_task_title` 10, `showcase_guard_task_reopen` 10,
`showcase_audit_task_completion` 10, `showcase_warn_over_budget` 5), 127
`sys_stamp_audit_update`, and 254 `sys_stamp_audit_insert` on
plugin-audit's 127 `sys_audit_log` and 127 `sys_activity` inserts.
- The card's hotcrm reading (17.7.0, a 354-row seed, about 45 s, 1,254
app hooks, 8 flow runs, 2 approvals, 8 emails) is far larger than
anything in this repo's examples. The dogfood fixture below carries the
hotcrm shape: a condition-free flow that notifies and opens an approval,
on seeded rows.

## The pins

- **The claim dispatches no automation**, measured on a booted app
(`seed-ownership-claim-dispatch.dogfood.test.ts`). Four seeded deals
carry a condition-free metadata hook and a condition-free record-change
flow (notify the owner, then an approval). The real chain is mounted:
automation, `RecordChangeTriggerPlugin`, approvals, messaging,
`AuditPlugin` and sharing. The first user signs up over `POST
/api/v1/auth/sign-up/email` (dev admin seed off). The claim window shows
0 metadata-hook dispatches, 0 flow runs, 0 approvals and 0
notifications, and every deal's `owner_id` is the admin. A positive
control (the admin's own `PATCH` of one deal) fires the hook twice and
runs the flow once, with its approval.
- **Audit and sharing still run (objectstack-ai#2922).** The same window has one
`sys_audit_log` update row per claimed deal, each recording the new
owner and carrying `created_at`. It also has one `sys_record_share` rule
grant per deal, from a criteria rule (`record.owner_id != null`, shared
with the `owner_id` field) whose grants only the claim's owner change
can earn. Before the sign-up there are 0 grants.
- **What the flag reaches**, measured on a real engine
(`claim-seed-ownership-dispatch.pin.test.ts`). A hook bound through
`bindHooksToEngine` (so it carries `meta`, like an app hook) gets 0
dispatches. A code-registered hook gets one per-row dispatch per claimed
row and phase, each with `isSystem`, `skipAutomations` and
`skipTriggers` true. `skipTriggers` is the one field
`RecordChangeTrigger`'s handler reads before dispatching a flow.
Control: a plain system predicate write over the same rows fires the
metadata hook 2 x N.
- **The per-row hook ceiling (mechanism hypothesis 2), measured.** With
`MAX_BULK_PER_ROW_HOOK_ROWS + 500` unowned rows, a `{ isSystem: true,
skipAutomations: true }` predicate write is still refused whole (`code`
and `limit` asserted, nothing written, no hook run). The engine counts
matched rows against the ceiling whenever any hook covers the object and
does not consult the flag. The claim then pages to every row (10 500 of
10 500), with 0 metadata-hook dispatches. `CLAIM_PAGE_ROWS` is
unchanged, because its derivation is still right.
- **Every caller (mechanism hypothesis 3).** Both callers write through
`claimSeedOwnership`: the promotion pass (`bootstrap-platform-admin.ts`,
inside the first sign-up) and the `app:seeded` settle pass
(`security-plugin.ts` `claimSeedOwnershipOnSettle`, on every boot
including warm boots). The changeset names both.

**Ablation** (`node scripts/ablation-replace.mjs`, anchor
`CLAIM_WRITE_CTX = { isSystem: true, skipAutomations: true };` replaced
with `CLAIM_WRITE_CTX = { isSystem: true };`, landed x1 to x0, blob
`fa63cffb37` to `7b581f3b26`):

- `ablation-dist-preflight` found the marker in `dist/index.js` and
`dist/index.mjs`.
- The claim unit test went red: `expected { isSystem: true } to deeply
equal { isSystem: true, …(1) }`.
- The real-engine pin went red twice: `a metadata-bound hook fired for
the claim: expected [ …(80) ] to deeply equal []`, and on the fallback
`expected [ …(21000) ] to deeply equal []`.
- The dogfood pin went red: `appHooks: 8, flowRuns: 4, approvals: 4,
notifications: 4` against all-zero.
- Restore: blob == HEAD and `git diff HEAD` empty,
`@objectstack/plugin-security` rebuilt, and `--absent` preflight shows
the marker gone from all 6 built files with a clean tree.

## Owner-change readers (first-party, in tree)

I enumerated every metadata-bound hook and record-triggered flow in
`examples/**` and `packages/**`. Outside test fixtures, `packages/**`
ships none. **None reads an `owner_id` change**, so this needs no
decision:

- **app-crm.** Hook `opportunity_stage_probability` (`crm_opportunity`,
before insert and update) reads `stage`. `convert-lead` is a screen
flow, not record-triggered.
- **app-showcase hooks** (`src/data/hooks/index.ts`).
`showcase_normalize_task_title` reads `title`,
`showcase_audit_task_completion` reads `done`,
`showcase_warn_over_budget` reads `spent`/`budget`,
`showcase_stamp_inquiry_defaults` reads `status`/`source` on insert, and
`showcase_guard_task_reopen` reads `done`.
- **app-showcase record-triggered flows**
(`src/automation/flows/index.ts` unless noted). Their start conditions
read `status` (`showcase_task_completed`, `_task_completed_slack`,
`_task_completed_rest_ping`, `_task_done_notify_owner`,
`_fan_out_notify`, `_resilient_sync`, `_project_closure`,
`_invoice_signoff`, `_expense_signoff`, `_committee_quorum`), `assignee`
(`showcase_task_assigned_notify`), `budget`
(`showcase_budget_approval`), `health` (`showcase_project_escalation`),
`priority` (`showcase_urgent_task_alert`) and `title`
(`showcase_dynamic_approval`, `dynamic-approval.flow.ts`). Three are
insert-only (`showcase_declarative_connector_ping`,
`_mcp_connector_echo`, `_task_follow_up`). The draft
`showcase_approver_bindings` (`approver-bindings.flow.ts`) has no
condition. Several notify `{record.owner}`, a business field, not
`owner_id`.
- **app-todo.** Hook `task_logic` and flow `task_completion` read
`status`.
- **Fixture only.** `packages/verify/src/handle.fixture.ts` hooks on
`hnd_deal` read no owner field.

## Gates and tests (head `aa21b6c3f9`)

- `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack`, re-derived on this change with no paths,
gives 69 families: the 57 at dispatch plus 12 for the changeset and the
new files. All 69 were run on `aa21b6c3f9`, exit code captured before
any pipe, every one `exit 0`. `--ran` with the exit codes: "69 derived
famil(ies) accounted for — 69 run, 0 NOT-MEASURED (a DERIVED zero …)".
- `check-tenant-audit-census`: "OK -- 233 write call sites certified".
The write context is a plain literal on purpose. Spelled `{ … } as const
satisfies ExecutionContext`, it moved this write from "decidably
elevated" to "elevation undecidable" in the census (122/103 against the
page's 123/102), because the census does not unwrap `satisfies`.
- `check:engine-double-contract`: "OK — 980 pinned". `check:nul-bytes`:
"OK (scanned 10064 text file(s) …)". `check:dual-build-cjs-loads`: "106
published require entry point(s) across 66 package(s) load", after
building the 8 packages its prerequisite named.
- `@objectstack/plugin-security`, after `pnpm --filter
'@objectstack/plugin-security^...' build`:
- `typecheck` passes: `tsc` plus `check:test-typecheck: OK … 0
error(s)`;
  - `vitest run` gives 169 files, 3640 passed, 45 skipped.
- Dogfood tests that drive the seed claim. Every `bootStack` boot runs
it through the dev admin seed; the new one runs it through REST.
- `--project isolated`: `seed-ownership-claim-dispatch`,
`owner-anchor-and-bulk-writes`, `authored-row-write-scope`,
`predicate-write-unreadable-not-matched`, `bulk-widener-probe` and
`admin-platform-admin-standing`, 6 files, 46 passed.
- `--project shared-showcase`: `showcase-private-owd` and
`showcase-public-read-owd`, 2 files, 8 passed.
  - `@objectstack/dogfood` `typecheck` passes.
- The rest of the dogfood suite is left to CI's Dogfood Regression Gate.
- `eslint --no-inline-config --format json` on the 4 changed `.ts` files
gives 4 files, 0 errors, 0 warnings. Each file matches the config
(`--print-config` exits 0). This repo's config enables no type-aware
linting (`eslint.config.mjs` near line 327: no `parserOptions.project`),
so this diff cannot move any untouched file's verdict. The repo-wide
`pnpm lint` is CI's.

## Acceptance notes

- **ObjectQL's `sys_stamp_audit_insert` / `sys_stamp_audit_update` are
skipped under `skipAutomations`.** They are bound through `ql.bindHooks`
(`packages/objectql/src/plugin.ts`, packageId `sys:audit`), so they
carry `meta`. The A/B log shows them among the 416 skipped dispatches.
- For this write that changes nothing. The claim has no user to stamp
into `updated_by`, and every driver stamps `created_at`/`updated_at`
itself. Measured on the dogfood fixture: the claimed rows' `updated_at`
advances (`…:55.456Z` to `…:57.042Z`), `updated_by` stays null as
before, and the claim's audit rows carry `created_at`.
- It does contradict the `ExecutionContext.skipAutomations` description,
which lists audit among the hooks that still run. For a data import with
"run automations" unchecked, `created_by`/`updated_by` stamping would be
skipped. That is NOT MEASURED. Noted, not filed. Carrier: none.
- **The multi-tenant twin, `claimOrgSeedOwnership`**
(`packages/plugins/organizations/src/claim-org-seed-ownership.ts`),
re-owns seed rows with single-id writes under a bare `{ isSystem: true
}`, so it has the same dispatch shape. It is not touched here. Its reach
is NOT MEASURED (it needs a multi-tenant boot). Carrier: none.
- **The draft `showcase_approver_bindings`** says "Draft on purpose",
but draft flows fire their triggers (service-automation logs that at
boot). At `56bf27affb` the first sign-up's claim ran it and opened 2
approval requests with no concrete approver. On this branch the claim no
longer reaches it. A user edit of a `showcase_field_zoo` row still
would; that is NOT MEASURED. Carrier: none.

References only: objectstack-ai#14530, objectstack-ai#14719, objectstack-ai#21486, objectstack-ai/hotcrm#2008.

---
_Generated by [Claude
Code](https://claude.ai/code/session_01WMQprn46CND82KmY8sZWBu)_

---------

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

Labels

backend Server-side behaviour — hooks, flows, actions ci/cd CI plumbing and the verification pipeline configuration Build and app configuration files dependencies Dependency bumps and lockfile changes documentation Improvements or additions to documentation metadata Declarative metadata — schema, security posture, UI surfaces

Projects

None yet

1 participant