Skip to content

cli: os build / os dev per-package author-time rules refuse an action param's record-picker reference to a dependency's object (object-reference-unknown), while the composed pass accepts it and ADR-0130 R1 accepts the field-level equivalent #18204

Description

@os-elon-musk

Finding (class b — two passes give one reference opposite verdicts)

In an ADR-0130 multi-package artifact, os build runs the author-time rules twice: once over the composed union (accepts) and once per package (refuses). An action declared by a module package whose param carries a record-picker reference to an object owned by the app package the module depends on is refused in the per-package pass with object-reference-unknown, whose text claims the reference is "inert at runtime". It is not: the composed artifact resolves it and the picker works.

Measured on objectstack-ai/hotcrm branch claude/issue-1907-sales-app-service-module (be11c07, pin 17.4.0): the service module's three crm_case activity actions (log_call, log_meeting, schedule_meeting, instantiated from the shared factory in the app package) carry attendee_contacts with reference: 'crm_contact' — an app-package object, and the module declares dependencies: { 'app.objectstack.hotcrm': '^3.1.0' }:

$ pnpm build   # with the per-stack permission refusal (objectstack#18202) probed away
Author-time rules failed inside the artifact's packages (6 issues)
  object-reference-unknown … reference 'crm_contact' … (log_call / log_meeting / schedule_meeting on crm_case, attendee_contacts)

The composed pass immediately before reports nothing for the same references. A Field.lookup('crm_contact') on a module-owned object is accepted by both passes (ADR-0130 R1, measured in #14122 §4) — so the platform accepts a cross-package reference at the field level and refuses the same reference at the action-param level, in the same build.

Where it lives

packages/cli/src/commands/compile.ts runs the per-package pass:

const asStack = packageBodyAsStack(pkg.body, artifactPackageEntries);
const pkgFindings = runAuthoringRules('build', { normalized: asStack, parsed: asStack,})

packageBodyAsStack already receives artifactPackageEntries — the hook for making the per-package stack dependency-aware exists; the composed pass's own fold is authoringRuleUnionStack (packages/cli/src/utils/stack-collections.ts). The rule itself (packages/lint/src/validate-object-references.ts) may need no change.

Ask

The per-package pass should resolve references against the package's declared dependency closure (or the whole artifact), like the composed pass does; the field-level and action-param-level rules should agree. The refusal must move, not disappear: a reference to an object no package in the artifact defines must still be refused, with a fixture proving it. Same root as objectstack#18202 and #18203: per-package author-time rules treating one package of a co-owned artifact as a closed world.

Dedupe words: object-reference-unknown, per-package author-time rules, action param reference, record picker reference, module dependency, ADR-0130 R1, packageBodyAsStack.

Related: objectstack-ai/hotcrm#1907 (blocked card), #18202, #18203, #17069 (the earlier empty-stack shape of the same two-pass problem), #14122 (the ADR-0130 tracker).

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

    bugSomething isn't workingdomain:clipriority:p1High: required for production / M2

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions