Skip to content

Cross-module drift detection for qualified default types (default alias/Type) #47

Description

@yavorpanayotov

Summary

check_default_field_schemas (added in #46) validates default Type x = { ... } object literals against the declared field schema of local entity/value types — flagging undeclared fields (allium.default.unknownField) and rule-14c empty-list targets (allium.list.emptyListNoElementType), recursing into nested object literals.

Qualified (imported) default types are currently skipped:

use "./gradient-policies.allium" as gp

default gp/Policy my_policy = {
    id: "p1",
    naem: "typo"   -- NOT flagged: gp/Policy's schema isn't visible to a single-module pass
}

This is the case the original request (juxt/allium#43, Gap B) centered on — a fragment importing Policy from a parent spec wants drift caught when the parent's schema changes. Local validation doesn't cover it.

Why it's deferred

Resolving an imported entity's field set requires cross-module context the single-module checker doesn't have. The single-file TypeScript analyzer cannot see other modules at all, so this would be a CLI multi-file-only capability — consistent with how qualified trigger resolution already works (resolved in the Rust CLI via CrossModuleContext, skipped in TS).

Proposed approach

Mirror the existing imported_triggers plumbing for entity field schemas:

  1. Add a collect_entity_field_schemas(module) -> HashMap<String, HashSet<String>> (entity/value name → declared field names) in allium-parser, analogous to collect_trigger_outputs.
  2. Add imported_entity_fields to CrossModuleContext in crates/allium/src/main.rs, built per-file by following use aliases to their target modules (the same alias→module resolution used for triggers).
  3. Thread it through analyze_with_cross_moduleCtx, and have check_default_field_schemas consult the imported schema for a qualified default alias/Type (look up alias → module → Type → field set), emitting allium.default.unknownField on drift.
  4. Aliases whose targets are outside the check set are never flagged (same convention as qualified triggers).
  5. TypeScript stays single-file: it continues to skip qualified defaults (document the asymmetry in the parity doc, as is already done for qualified triggers).

Acceptance

  • A qualified default with a field not declared on the imported entity is flagged in multi-file allium check.
  • A qualified default whose imported module is outside the check set is not flagged.
  • No regression to local-default validation; TS behaviour unchanged.

Refs juxt/allium#43. Follow-up to #46.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions