Skip to content

verify: the in-process handle boots a leaner stack than serve and has no door for eight things an app's tests need (requires[] capabilities, system/predicate update, the form door, user-less triggers, …), measured by hotcrm#2013 #22301

Description

@objectstack-fleet

Ruled: 6070767186 · letter A (item 1) · 2026-10-08T23:05Z

Filing gate: ① product defects in a published package, reach measured. Class (a). reach: named producer. objectstack-ai/hotcrm's test suite was ported onto @objectstack/verify 17.7.0 (PR objectstack-ai/hotcrm#2013 for objectstack-ai/hotcrm#1595, the hotcrm consequence of objectstack#15951). Each item below was measured there with the handle's own calls.

Who acts on it: the objectstack triage seat routes it; the fixes land in packages/verify (item 1 also touches packages/cli). Found by the dev of hotcrm#1595 (session session_012zh91QzFgePbkmuHnugLN3); the repo:hotcrm seat located the sites. ⛔ Not a claim.

Why it matters: the maintainer's B′ ruling (2026-09-05, on objectstack#15951) put test execution on the platform: an app's tests reach the real engine through this handle and nothing hand-built. hotcrm#1595's rule: "a behaviour the handle cannot express is a platform finding … keep that one local helper path until the fix is pinned … ⛔ never re-grow a local stand-in". hotcrm therefore keeps exactly one local path per item, in test/helpers/verify-stack.ts. Each path calls the engine's own service on the verify-booted kernel; none re-implements the engine. Every item closed here deletes one of them.

The gaps (measured on 17.7.0; sites at the @objectstack/*@17.7.0 commit)

  1. bootStack ignores the app's requires[]. objectstack serve mounts the capability providers an app requires. verify/src/harness.ts:516-730 boots a fixed plugin set, offering only automation and extraPlugins. The mapping lives on the Serve class (CAPABILITY_PROVIDERS, cli/src/commands/serve.ts:1867; CapabilitySpec unexported at :959). The handle cannot reuse it, so an app names the plugins by hand. Measured on hotcrm without them: no sys_inbox_message, no sys_approval_request, no sys_activity, and no record-change flow fired on a write. hotcrm names five: triggers, approvals, messaging, audit, email.
  2. No system-context UPDATE door. seed only inserts (handle.ts:401-405), and hooks.run always runs as a person.
  3. No predicate (multi: true) update door. hooks.run addresses one row by input.id, and REST updateMany iterates by id. The engine's predicate path, where 17.7.0 binds each row's pre-image, has no handle door.
  4. The anonymous form door is not served. POST /api/v1/forms/:slug/submit (registered by rest/src/rest-server.ts:10720) answers ENDPOINT_NOT_FOUND through the handle's dispatcher. An app's web-to-lead / web-to-case branches can only be reached by reproducing the door's execution context (publicFormGrant, guest_portal, anonymous).
  5. No door for a user-less record trigger, or for a record the engine no longer holds. Every handle write fires as a person, and seed skips record-change flows. An integration's or system job's write, and a record deleted between the trigger and the flow's get_record, cannot be driven.
  6. No observation of what a hook handed the engine. A refused write leaves no row, an async: true hook's completion is invisible (the write that fired it has already returned), and a refusal cannot be staged without a spy on the engine.
  7. No lowered-body door. The handle boots the source config, so the production body-only path, and its refusal envelope, are not what a handle test runs.
  8. automation.evaluateCondition is not fronted. A truth table over row shapes that no write produces needs the kernel service.
  9. Seed replay under bootStack refuses cel date values. hotcrm's seed uses the documented cel`daysFromNow(..)` form (content/docs/data-modeling/seed-data.mdx:387-397). Each verify boot logs ~478 insert WARNs "must be a valid datetime (ISO-8601)" (campaign, case, event, opportunity, lead and account seeds), and the rows are missing. serve resolves these (seed-loader.ts:1138 → formula/src/seed-eval.ts:74). The only warn-level insert-failure line is AppPlugin's raw-insert fallback (runtime/src/app-plugin.ts:1527-1534, :1542-1548), which runs when no metadata service is mounted or SeedLoaderService throws. Root cause NOT MEASURED. objectstack#21663 (closed) named these raw-cel paths.

Acceptance

Each item gets a handle door, or a stated decision that the door is out of scope. Each then lets hotcrm delete the matching local path in test/helpers/verify-stack.ts: extraPlugins list, systemUpdate, predicateUpdate, guestInsert, runRecordFlow, recordEngineWrites, runShippedHook, conditionHolds. Item 9: a verify boot of an app with cel-dated seeds stores those rows.

Duplicate check

gh search is refused in this container (GraphQL and REST search answer 403). So all 9,565 objectstack issues were listed and matched case-insensitively:

None is a duplicate. The origin is #15951 (closed). Open #15953 (derived proof families) and #15952 (docs + scaffold) are siblings; #21663 (closed) is item 9's nearest record.


Generated by Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratebugSomething isn't workingdomain:specpm:queuepriority:p2Medium: important, M3

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions