Skip to content

Add schema evolution guardrails and add_field MCP tool#8

Merged
mgoldsborough merged 6 commits intomainfrom
feat/schema-evolution
Mar 27, 2026
Merged

Add schema evolution guardrails and add_field MCP tool#8
mgoldsborough merged 6 commits intomainfrom
feat/schema-evolution

Conversation

@mgoldsborough
Copy link
Copy Markdown
Contributor

Summary

  • validate_schema_change() — pure function that compares two schema dicts and returns diagnostics for unsafe changes: required-without-default (error), type change (error), enum narrowing (error), field removal (warning)
  • Required-without-default warningvalidate_entity() now logs a warning when required fields lack defaults, catching the footgun early without blocking
  • UpjackApp.reload_schema() — hot-reloads an entity schema from disk via new manifest_dir tracking on the app instance
  • add_field MCP tool — lets agents add fields to a running app with structural guardrails: default is required, type is validated, validate_schema_change() gates the write, then schema is reloaded in-place

Test plan

  • TestValidateSchemaChange — 8 cases (no change, required+default ok, required no default, type change, enum narrow/widen, field removed, multiple issues)
  • TestRequiredWithoutDefaultWarning — 3 cases via caplog (warns, no warn with default, no warn for base fields)
  • TestReloadSchema — 3 cases (picks up file change, unknown entity, no manifest_dir)
  • TestAddFieldTool — 7 cases (registered, writes schema, adds to required, reload+hydrate roundtrip, rejects invalid type, rejects bad default, rejects type conflict)
  • Existing tests updated for add_field tool presence (tool count assertions)
  • make check passes (format + lint + typecheck + 255 tests)

mgoldsborough and others added 2 commits March 5, 2026 11:32
- validate_schema_change(): pure function that detects unsafe schema
  changes (required-without-default, type changes, enum narrowing,
  field removal)
- _check_required_without_defaults(): warns at validation time when
  required fields lack defaults (catches the footgun early)
- UpjackApp.reload_schema(): hot-reloads entity schema from disk
  with manifest_dir tracking
- add_field MCP tool: lets agents add fields to running apps with
  structural guardrails (default required, type validation,
  schema change validation before write)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
get_entity, list_entities, update_entity, and search_entities now
accept an optional schema parameter. When provided, missing fields
are filled with schema defaults before returning — enabling seamless
schema evolution without backfill migrations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- deepcopy schema defaults so hydrated entities don't share mutable
  objects (lists, dicts)
- Validate field names against [a-z][a-z0-9_]* pattern
- Reject reserved base entity field names (id, type, status, etc.)
- Block path traversal in schema paths
- Reject adding a field that already exists, even with matching type
json.dumps doesn't include a trailing newline, causing "No newline at
end of file" noise in git diffs.
@mgoldsborough mgoldsborough added the qa-reviewed QA review completed with no critical issues label Mar 27, 2026
Tests add_field + hydrate-on-read against real CRM, Todo, and Research
Assistant schemas (allOf + $ref composition). Covers get, list, and
search read paths after field addition.
@mgoldsborough mgoldsborough merged commit 738d2c4 into main Mar 27, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

qa-reviewed QA review completed with no critical issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant