Skip to content

Validate default literals against entity schema (drift) + rule 14c#46

Merged
yavorpanayotov merged 1 commit into
mainfrom
feat/default-field-validation
Jun 16, 2026
Merged

Validate default literals against entity schema (drift) + rule 14c#46
yavorpanayotov merged 1 commit into
mainfrom
feat/default-field-validation

Conversation

@yavorpanayotov

Copy link
Copy Markdown
Collaborator

Actions the two follow-ups identified during review of juxt/allium#43: Gap B drift detection and language-reference rule 14c.

What it does

A new check_default_field_schemas (Rust) / findDefaultFieldSchemaIssues (TS, walks the front-end AST) validates default Type x = { ... } object literals against the declared schema of local entity/value types:

  • Gap B driftallium.default.unknownField: a field the type doesn't declare is flagged, recursing into nested object literals (so a stale field inside predicate: { ... } is checked against the nested value type — matching the reporter's shape).
  • Rule 14callium.list.emptyListNoElementType: an empty [] whose target field isn't a List<T> has no element type to infer. Empty lists in List<T> fields stay valid.

Scope / honesty

  • Keyed to local entity/value declarations. Qualified (imported) default types are skipped — their field schema isn't visible to a single-module pass. True cross-module drift detection would need imported-entity-field plumbing through CrossModuleContext (like triggers) and would be CLI-multi-file-only (the single-file TS analyzer can't see other modules), so it's a deliberate follow-up rather than part of this PR.
  • No false positives: verified zero new diagnostics across every checked-in .allium spec in the repo.

Tests

  • Rust: cargo test --workspace green; added 6 tests (unknown field, nested drift, known-fields-ok, empty-list-in-list-ok, empty-list-in-non-list-flagged, qualified-skip).
  • TypeScript: npm run test 330 pass (added 3); npm run lint clean.
  • Rust↔TS parity confirmed case-by-case.

Parity doc + diagnostic-code table updated (allium.default.unknownField, allium.list.emptyListNoElementType).

Refs juxt/allium#43

🤖 Generated with Claude Code

Follow-up to juxt/allium#43.

Adds `check_default_field_schemas` (and the TypeScript `findDefaultFieldSchemaIssues`,
which walks the front-end AST) validating `default Type x = { ... }` object
literals against the declared schema of local entity/value types:

- Gap B drift: a field the type does not declare is reported as
  `allium.default.unknownField`, recursing into nested object literals (so a
  stale field inside `predicate: { ... }` is caught against the nested type).
- Rule 14c: an empty list literal whose target field is not a `List<T>` is
  reported as `allium.list.emptyListNoElementType` — it has no element type to
  infer. Empty lists in `List<T>` fields remain valid.

Validation is keyed to local entity/value declarations. Qualified (imported)
default types are skipped: their field schema is not visible to a single-module
pass, and cross-module field plumbing would be CLI-multi-file-only. Verified
zero new diagnostics across all checked-in example specs.

Rust and TypeScript kept in parity; parity doc and diagnostic-code table updated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@yavorpanayotov yavorpanayotov merged commit bfcc76d into main Jun 16, 2026
2 checks passed
@yavorpanayotov yavorpanayotov deleted the feat/default-field-validation branch June 16, 2026 14:12
yavorpanayotov added a commit to juxt/allium that referenced this pull request Jun 16, 2026
Adds validation rule 24b: every field in a `default` object literal must be
declared on the named entity/value type, recursing into nested object literals,
so field renames/removals surface as drift errors at check time. Complements the
existing 24a (qualified-type schema resolution) and 14c (empty-list element
type). Implemented in juxt/allium-tools#46.

Refs #43

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant