Skip to content

chore(deps): upgrade the ObjectStack platform to 18.0.0-next.1 - #2106

Merged
objectstack-fleet[bot] merged 8 commits into
mainfrom
claude/issue-2105-objectstack-18-next-1
Oct 14, 2026
Merged

objectstack-fleet[bot] merged 8 commits into
mainfrom
claude/issue-2105-objectstack-18-next-1

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #2105
Clause-②: no

Description

This PR upgrades HotCRM from @objectstack/* 18.0.0-next.0 to 18.0.0-next.1, on the maintainer's order 「18.0.0-next.1 已发布,升级试试」.

18.0.0-next.1 is a prerelease step inside protocol major 18. It made pnpm validate fail once and pnpm test fail in 9 files. Each failure traced to a release-note line, and each fix below applies that line's own FROM → TO. No platform regression was found on the new pin, so nothing here routes around the platform.

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 #2105

main was merged at 850f75c2 (#2102, which landed while this was in flight). That merge was clean.

Changes Made

Pins.

  • All 23 @objectstack/* packages move 18.0.0-next.0 → 18.0.0-next.1, exact: 19 in dependencies, 4 in devDependencies. The registry was checked for each of the 23 before the bump: every one carries 18.0.0-next.1 on dist-tag next.
  • specVersion and engines.protocol move to ^18.0.0-next.1 in objectstack.manifest.json, src/sales/index.ts and src/service/index.ts.

Lockfile delta. pnpm install regenerated pnpm-lock.yaml.

  • packages: keys go from 705 to 707.
  • The 55 @objectstack/* keys moved one for one.
  • @objectstack/connector-imap@18.0.0-next.1 and postal-mime@4.0.6 were added, both pulled in by @objectstack/service-mailbox.
  • No other third-party package changed version. The install's one peer warning (better-auth wants better-sqlite3@^12, 13.0.3 installed) is the same set of versions as on main.

Release notes read

  • The v18 page (content/docs/releases/v18/index.mdx, read from objectstack's source at the next.1 release commit 0c52e430): docs.objectstack.ai refuses this container's egress. It says the changesets are the record. Its one new paragraph since next.0 is about re-installing the AI skills (Upgrading step 4). HotCRM has no @objectstack/skills dependency, no skills lock file and no installed skill, so there is nothing to re-install.
  • Every installed package's CHANGELOG.md section for 18.0.0-next.1: 55 packages, 70 distinct changeset entries after de-duplication (2 Major, 47 Minor, 21 Patch). Each was checked against src/, test/ and scripts/.

Per-change list: the next.1 changes that reached this app

  1. A controlled_by_parent object derives its master from exactly one required master_detail (spec 76815b9, objectstack#23100).
    • os validate refused crm_article_feedback (exit 1).
    • The changeset's FROM → TO table names HotCRM's three objects. Its prescription is applied as written:
      • crm_campaign_member.crm_campaign becomes Field.masterDetail, deleteBehavior: 'restrict';
      • crm_event_attendee.crm_event becomes Field.masterDetail, deleteBehavior: 'restrict';
      • crm_article_feedback.crm_knowledge_article becomes Field.masterDetail, cascade kept.
    • Deletes behave as before: a campaign or meeting with rows still refuses to delete, and an article still takes its feedback with it.
    • campaign-member-cascade and event-attendee-cascade pin the new declaration. The attendee suite's end-to-end refusal case passes unchanged.
    • The object comments that explained the old lookup shape are rewritten. So are the two line-item objects' comments, which said the resolver accepts a required lookup.
  2. A notification takes the organization of what it is about; one no organization owns is refused (24e064f, objectstack#23284).
    • A schedule run carries no organization. On an install holding more than one organization, every scheduled notify was refused with ERR_SYSTEM_WRITE_ORGANIZATION_REQUIRED, and the sweep abandoned that record at the notify node.
    • flow-scheduled-org-partition went red: contract_renewal opened no renewal deal, and opportunity_stagnation wrote no nudge task.
    • Measured with a control. On the boot's single organization the same run notifies and writes the task. After one more organization is seeded, the emit is refused, and the error was read off the messaging service.
    • The release note's remedy is to name the record the notification is about. It is applied to all five schedule-run notify nodes: contract_renewal, contract_expiration, opportunity_stagnation, task_due_reminder and case_sla_monitor now carry sourceObject + sourceId, naming the loop record their actionUrl already links to.
    • Record-change and screen flows keep the trigger record's organization and are unchanged.
  3. IdentityObjectsPlugin keeps the single posture's Default Organization at boot (917b1a0).
    • Four reduced test kernels (cascade-guard-messages, case-creation-date, freeze-guard-reference-cleanup, lead-duplicate-link-cleanup) inserted their own Default Organization. The insert was refused on the slug, and each suite failed in beforeAll.
    • The release note says to drop the insert and read the one the boot created. The insert is dropped.
  4. The security-catalog row objects are retired (66949b7, ADR-0131 D3).
    • hierarchy-read-depth wrote its three throwaway permission sets as sys_permission_set rows.
    • They are now saved through PUT /api/v1/meta/permission/:name, the replacement the note names.
    • The suite's org-wide control arm still sees every seeded row, so the sets grant.

next.1 changes measured as not reaching this app

  • Component props findings are now errors (4f68ba1): 0 findings. pnpm validate, build and lint are green.
  • Flow conditions are CEL only; the single-brace resolver is deleted (7958bdf, Major): no braced or template-dialect condition exists here. The three direct evaluateCondition calls in tests pass CEL (an envelope, or a bare CEL string), with no {…} hole, and they pass.
  • One default record page per object (5f37d36): each of crm_lead, crm_opportunity and crm_case has one, and home is not a record page.
  • Anonymous flow endpoint paired with a system flow (c857a93): this app declares no apis:.
  • View-level api data source retired (1912af4); page action row onSuccess / operation / navigation narrowings (4d1e4a8, b529a5c, 1623faf, 775ed65); token at a typed builtin config key (ca0bdbc): none authored here. os validate is green.
  • Rolling last_N_days presets now close on today (b4d573a): this app authors no last_N_days preset. One report window is written { $gte: '{30_days_ago}' }, the shape the note advises closing with $lte: '{today}'. Its evaluation does not change on next.1, so it is left as it is and noted under Acceptance notes.
  • guest record-share recipient retired (345d1be) and the guest grants channel (37510aa, e790cfc): this app writes no guest share. The public form doors keep their own posture: both forms were submitted in the browser pass below.
  • runDashboardWindowProofs loses its fourth argument (06dbc4e): not called here.
  • The ADR-0069 posture refusals, /data and /ui anonymous 401, ?package= / 409 metadata doors, migration-ceremony steps, IMAP sync and storage attachFile: no app surface reaches them. All 179 test files pass.

Pin-claim sweep (AGENTS.md "Platform Upgrades" step 5)

18.0.0-next.0 appears 120 times outside the lockfile and CHANGELOG.md, and each hit was classified by hand. The large majority read "since 18.0.0-next.0 …", "until 18.0.0-next.0 …" or "measured on …". Those are dated facts that stay true, and they are left as written.

Re-scoped because they asserted next.0 is the pin:

A version-agnostic shape search ("the pin", "pinned", "installed platform", "current platform") found two more claims that next.1 makes false, without a version token:

  • The line-item comments: "the resolver accepts a REQUIRED LOOKUP as the parent". Corrected.
  • service-agent.profile.ts: "PositionSchema rejects permissionSets". On next.1 it accepts them (measured). The note is now dated. The name binding it explains still resolves: security/explain for a demo user holding only the service_agent position answers permissionSets: [service_agent, member_default].

A grep finds only text that carries a version token or a pin word. A stale fact stated in other words is found only by reading, so this sweep is not claimed complete.

Upstream unlock table (card §6)

The release commit for 18.0.0-next.1 is objectstack 0c52e430. The console bundle's dist/.objectui-sha is objectui b9814b33; next.0's was 1fb1ced3. Each "in the pin" verdict comes from the GitHub compare API, with a known-ancestor control leg per repository: next.0's release commit d889448b reads ahead of 0c52e430, and 1fb1ced3 reads ahead of b9814b33.

Card State Fix In 18.0.0-next.1?
objectstack#23221 (hotcrm#2088) closed 2026-10-14 objectstack#23458, 584e7373 No. It merged at 12:00:41Z. Compare 584e7373...0c52e430 reads behind by 8: the release commit comes before the fix.
objectui#12357 (hotcrm#2095) open none No
objectstack#23279 open none No
objectstack#23284 closed 2026-10-13 objectstack#23340, 24e064fc Yes. CHANGELOG entry 24e064f (objectql, service-messaging, service-automation, plugin-approvals). It is not in next.0. This PR adopts its remedy (item 2 above).
objectui#12330 closed 2026-10-14 objectui#12340, 2b06a91e Yes. Console CHANGELOG "(objectui 2b06a91e6)". It is an ancestor of b9814b33 and not of 1fb1ced3.
objectui#12331 open objectui#12336, 2722d33c ("Part of") Partly. #12336 is in the pin (console CHANGELOG "(objectui 2722d33c5)"). It widens the flow-launch selection rule. Its author could not reproduce the card's script-action symptom, and the card stays open.
objectui#12332 open none: #12336 leaves BulkActionDialog.tsx untouched No
objectui#12333 open none No
objectstack#23255 open none No
objectstack#23256 open none: the two cross-referenced PRs are not its fix No
objectui#12220 closed 2026-10-12 objectui#12231, 5c2982ad Yes. It was already in next.0's console (an ancestor of 1fb1ced3).
objectui#12228 closed 2026-10-12 objectui#12259, 0cd322d7 Yes. It was already in next.0's console.
objectstack#23032 closed 2026-10-12 objectstack#23102, 39e93efe (docs) Yes. It was already in next.0 (an ancestor of d889448b).
objectstack#22722 closed 2026-10-10 coordination parent, no fix commit of its own n/a. It was closed before next.0 was cut, and its children are judged on their own cards.
objectui#12358 open none No
objectui#12359 open none No

Testing

Every link of pnpm verify ran at HEAD 19a5418f under os-verify-lock.sh, on a clean tree:

Link Exit Result
pnpm validate 0 ✓ Validation passed: 18 Objects, 357 Fields, 33 Flows
pnpm typecheck 0 tsc --noEmit, no output (test/** is in tsconfig.json's include)
pnpm lint 0 18 suggestion(s), the same lines as main on next.0
pnpm lint:i18n-gate 0 ✓ i18n lint gate: 0 i18n/missing-* issues
pnpm hygiene 0 ✓ source hygiene clean
pnpm hygiene:tokens 0 ✓ source token ratchet clean
pnpm build 0 ✓ Build complete, 8 author-time warning(s), the same lines as main on next.0 (the approval-slate notes and hierarchy-security)
pnpm test 0 Test Files 179 passed (179), Tests 3660 passed / 1 skipped (3661), 506 s

On the bump alone, before any adaptation, at a972317b: Test Files 9 failed / 170 passed, Tests 6 failed / 3561 passed / 87 skipped. Every one of those failures is one of the four items above, or one of the two docs guards (STATUS.md and What's new).

Browser pass. Chromium at /opt/pw-browsers/chromium, own objectstack dev on port 4108 over a fresh database, pnpm demo:staff against it. Results were read with DOM and REST probes.

  • Dashboards (admin). All five dashboards draw: Executive, Sales, Service, Sales Activity and CRM Overview.
    • 4 to 5 chart wrappers each, and 13 to 21 chart marks;
    • 67 analytics/dataset/query calls, all 200;
    • no console errors;
    • no timezone dialog on the fresh database.
  • Leads (as na.rep).
    • New Lead created two leads through the form.
    • Convert Lead opens Conversion Details, and Submit converts each one.
    • A unique company got a new account, Walk Newco ….
    • Company "Acme Corporation" was matched to the existing Acme account: same id, is_converted: true, status: converted, contact linked.
  • Opportunities and quotes (as na.rep); cases and knowledge (as service.agent); campaigns and events (as admin). Lists and record pages render, with no console errors and no failed API call.
  • Master-detail surfaces changed here.
    • Enroll Members on a campaign added members (4 → 7). The Related tab lists them with the curated Added Date column, which comes only from relatedListColumns on the now-master-detail field.
    • Deleting that campaign, or a meeting with an attendee, answers 409 DELETE_RESTRICTED, and the parent survives.
    • Helpful on an article, as the service agent, writes a feedback row she can read back.
  • Public web forms (anonymous).
    • /forms/contact-us and /forms/support render and submit (201).
    • A web lead and case CASE-00039 land with an owner, and the case is auto-assigned to the service agent.

Token readings, origin/main → this branch:

Package Business semantics Interaction layer Authored total
src/sales 58,637 → 58,693 28,295 → 28,295 103,276 → 103,332
src/service 13,122 → 13,146 5,602 → 5,602 22,032 → 22,056
src/revenue 15,745 → 15,794 2,165 → 2,165 18,885 → 18,934
src/marketing 8,027 → 8,037 886 → 886 9,132 → 9,142

Diff size: 29 files, 1,313 changed lines (291 without pnpm-lock.yaml).

Screenshots

Captured in the session that ran this upgrade, not committed.

Risk

  • 18.0.0-next.1 is a prerelease, and the protocol major is still 18. A 17.x host still refuses the artifact at the handshake.
  • The three parent fields change type, from lookup to master_detail. The stored column is the same id column, and access and delete behaviour are as before (measured above).
    • A deployment that customized these fields in Studio keeps its stored overlay.
    • next.1's os migrate meta --stored lists a stored object still on a required-lookup master. It does not rewrite it.
  • Scheduled notifications now link to their record, which changes their inbox click-through. Before, they had none.

Rollback: revert this PR. The next.0 pins, the lockfile and the three lookup fields come back together, and no data migration ran.

Checklist

  • I have added a changeset (.changeset/2105-objectstack-18-next-1.md)
  • 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. The 8 build warnings and 18 lint suggestions are line-for-line those of main (850f75c2) on next.0, measured in a throwaway worktree.
  • I have added tests that prove my fix is effective or that my feature works: the adapted pins above
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published (@objectstack/* 18.0.0-next.1 is on npm)

Acceptance notes

  • Run history on a multi-organization single install. While a scheduled sweep runs on an install holding two organizations, the engine logs run-history persist failed … Insert on 'sys_automation_run' was REFUSED. That happens in the test harness, with or without this PR's notify change. It was measured in-process only, not through a public door. It is a platform write, not app metadata, and it is recorded here rather than filed.
  • Release-notes host. docs.objectstack.ai answered 403 at this container's egress proxy. The v18 page and the Upgrading page were read from objectstack's own source at the next.1 release commit 0c52e430.
  • test/demo-staffing.test.ts still lists sys_position_permission_set among the identity tables the app may never write. next.1 retires that object. A retired name on a deny list cannot make the guard pass wrongly, so it is left as it is.
  • An open rolling window in churn.report.ts. Recently Lost Opportunities filters close_date: { $gte: '{30_days_ago}' }. A closed-lost deal whose close date lies in the future would count in it. next.1's preset note (b4d573a) advises closing such windows with $lte: '{today}'. The bump does not change this window's evaluation, and nobody is carrying the change.
  • One console 404 (a non-API resource). It showed during the first rep and anonymous walks and did not reproduce when the pages were re-checked for 404 URLs. It is not attributed.

Generated by Claude Code

All 23 @objectstack/* pins (19 dependencies, 4 devDependencies) move
18.0.0-next.0 -> 18.0.0-next.1 together, exact. The lockfile was
regenerated by pnpm install, not edited by hand: 705 -> 707 package
keys; the 55 @objectstack/* keys moved one for one, and
@objectstack/connector-imap@18.0.0-next.1 plus postal-mime@4.0.6 arrive
through @objectstack/service-mailbox. No other third-party package
changed version.

Claude-Session: https://claude.ai/code/session_01P8mZuzuyZAHSrgQKmv6ASv

Co-authored-by: Claude <noreply@anthropic.com>
- crm_campaign_member, crm_event_attendee and crm_article_feedback are
  controlled_by_parent objects whose master was a required lookup.
  @objectstack/spec 18.0.0-next.1 (76815b9, #23100) derives a master
  from exactly one required master_detail and refuses the lookup shape
  at parse, so os validate exited 1. Each parent field becomes
  Field.masterDetail, as the release note's FROM -> TO table for these
  three objects prescribes: deleteBehavior 'restrict' on crm_campaign
  and crm_event (a parent with rows still cannot be deleted), 'cascade'
  kept on crm_knowledge_article.
- specVersion and engines.protocol move to ^18.0.0-next.1 in
  objectstack.manifest.json, src/sales/index.ts and src/service/index.ts,
  as test/docs-declared-versions.test.ts holds them to the installed
  @objectstack/spec. The major is unchanged, so the handshake is too.

Claude-Session: https://claude.ai/code/session_01P8mZuzuyZAHSrgQKmv6ASv

Co-authored-by: Claude <noreply@anthropic.com>
18.0.0-next.1 (24e064f, objectstack#23284) gives a notification the
organization of what it is about and refuses one no organization owns.
A schedule run carries no organization, so on an install holding more
than one organization each scheduled notify was refused with
ERR_SYSTEM_WRITE_ORGANIZATION_REQUIRED and the run abandoned that item
at the notify node: contract_renewal opened no renewal deal and
opportunity_stagnation wrote no nudge task (flow-scheduled-org-partition,
red on the bump). Measured with a control: on the boot's one
organization the same run notifies and writes the task.

The release note's remedy is applied to all five schedule-run notify
nodes (contract_renewal, contract_expiration, opportunity_stagnation,
task_due_reminder, case_sla_monitor): sourceObject + sourceId name the
loop record, the one actionUrl already links to. Record-change and
screen flows keep the trigger record's organization and are unchanged.

Claude-Session: https://claude.ai/code/session_01P8mZuzuyZAHSrgQKmv6ASv

Co-authored-by: Claude <noreply@anthropic.com>
- The four reduced kernels that mount createIdentityObjectsPlugin()
  (cascade-guard-messages, case-creation-date,
  freeze-guard-reference-cleanup, lead-duplicate-link-cleanup) no longer
  insert their own Default Organization. 18.0.0-next.1 (917b1a0) has the
  plugin create it at boot under `single`, so the insert was refused on
  the slug and every suite failed in beforeAll; the release note says to
  drop the insert and read the one the boot created.
- hierarchy-read-depth saves its three throwaway permission sets through
  PUT /api/v1/meta/permission/:name. 18.0.0-next.1 (66949b7) retires the
  sys_permission_set object and names that door as its replacement. The
  org-wide control arm still sees every seeded row, so the sets grant.
- campaign-member-cascade and event-attendee-cascade pin the parent as a
  required master_detail on `restrict`, the shape the cbp change moved it
  to; the business fact they guard (a parent with rows refuses to
  delete) is unchanged, and the attendee suite's end-to-end refusal case
  passes on the new pin.

Claude-Session: https://claude.ai/code/session_01P8mZuzuyZAHSrgQKmv6ASv

Co-authored-by: Claude <noreply@anthropic.com>
- docs/STATUS.md's runtime table and the three What's new pages state
  18.0.0-next.1 and ^18.0.0-next.1 for the release after 4.0.1.
- campaign-enrollment.flow.ts dates its "the pin" note per release.
- The opportunity and quote line-item comments no longer say the
  relation resolver accepts a required lookup as the parent: next.1
  derives a master from one required master_detail only.
- service-agent.profile.ts marks its PositionSchema premise as dated:
  on next.1 PositionSchema accepts permissionSets (measured) and
  sys_position_permission_set is retired.

Claude-Session: https://claude.ai/code/session_01P8mZuzuyZAHSrgQKmv6ASv

Co-authored-by: Claude <noreply@anthropic.com>
…n 18.0.0-next.1

Measured in the #2105 browser pass: security/explain for a demo user
holding only the service_agent position answers
permissionSets [service_agent, member_default].

Claude-Session: https://claude.ai/code/session_01P8mZuzuyZAHSrgQKmv6ASv

Co-authored-by: Claude <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 14, 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 14, 2026 1:44pm 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 backend Server-side behaviour — hooks, flows, actions labels Oct 14, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对

复核人:repo:hotcrm 执行席(#1353)· 判决 ACCEPT · 钉 head 19a5418f9f543d4547a649177110d865dfacd8aa · 2026-10-14T13:58Z

形态:一卡一 PR,Fixes #2105,Clause-②: no;29 文件,+709/−604 = 1,313 行(含 lockfile,< 3,000);路径面无 governed 面(无 AGENTS.md/CLAUDE.md/.claude/**/skills/**/.github/workflows/**)→ 非 Tier H,席位落地。

前提实测:23 处 @objectstack/* pin → 18.0.0-next.1;objectstack.manifest.json、src/sales/index.ts、src/service/index.ts 的 specVersion / engines.protocol → ^18.0.0-next.1。随版调整逐项对上游提交:crm_campaign_member.crm_campaign、crm_event_attendee.crm_event → Field.masterDetail(…, { deleteBehavior: 'restrict' }),crm_article_feedback.crm_knowledge_article → masterDetail cascade(spec 76815b9);五个 schedule notify 节点补 sourceObject+sourceId(objectstack#23284 / 24e064f);四个测试 kit 去掉自插 Default Organization(917b1a0);hierarchy-read-depth 改走 PUT /api/v1/meta/permission/:name(66949b7)。main 850f75c 是 head 的祖先。

门禁 check-runs(钉 head):Build and Test (22.x) ✓ · Typecheck and Build ✓ · Quality Checks ✓ · Check Changeset ✓ · Playwright ✓ · link-check ✓ · CodeQL ✓ · Analyze Code (javascript) ✓ · Label Pull Request ✓ · Vercel Preview Comments ✓ — 10/10 success,mergeable_state clean。

接受的偏差:STATUS.md / What's new ×3 的 pin 声明随版重定范围,属本卡升级第 5 步,非扩写。

范围外去向:@objectstack/skills 目录接入不在本 PR——新依赖且落 governed 面,维护者要再开卡(席位与 dev 同荐不接)。解锁表:objectstack#23221 的修复 584e7373 在 next.1 发版提交 0c52e430 之后,#2088 维持 pm:blocked;#2095 维持在 objectui#12357;本次无 hotcrm 卡解锁。

落地条款:席位经中继 pr_ready + automerge_enable,以 objectstack-fleet[bot] 入合并队列;合并后在 #2105 落探针表。

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 14, 2026 14:00
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 14, 2026
Merged via the queue into main with commit f4ac253 Oct 14, 2026
11 checks passed
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 dependencies Dependency bumps and lockfile changes documentation Improvements or additions to documentation metadata Declarative metadata — schema, security posture, UI surfaces

Projects

None yet

Development

Successfully merging this pull request may close these issues.

chore(deps): upgrade the ObjectStack platform to 18.0.0-next.1

2 participants